/** * Re-run a previous call by passing in the call's struct. * Note: When calls are re-run a retry=1 property is added, and that is incremented for each re-call. You should check * that value to avoid re-calling failed methods in an infinite loop. * * Part of the Daemon API - Use from your daemon to retry a given call * * @example You set a timeout handler using onTimeout. The worker will pass the timed-out call to the handler as a * stdClass object. You can re-run it by passing the object here. * @param stdClass $call * @return bool */ public function retry(Core_Worker_Call $call) { if (empty($call->method)) { throw new Exception(__METHOD__ . " Failed. A valid call struct is required."); } $this->log("Retrying Call {$call->id} To `{$call->method}`"); $call->retry(); return $this->call($call); }
/** * Retrieves a message from the queue * @param $desired_type * @return Core_Worker_Call */ public function get($desired_type, $blocking = false) { $blocking = $blocking ? 0 : MSG_IPC_NOWAIT; $message_type = $message = $message_error = null; msg_receive($this->queue, $desired_type, $message_type, $this->memory_allocation, $message, true, $blocking, $message_error); if (!$message) { $this->error($message_error); return false; } $that = $this; switch ($message['status']) { case Core_Worker_Mediator::UNCALLED: $decoder = function ($message) use($that) { $call = shm_get_var($that->shm, $message['call_id']); if ($message['microtime'] < $call->time[Core_Worker_Mediator::UNCALLED]) { // Has been requeued - Cancel this call $call->cancelled(); } return $call; }; break; case Core_Worker_Mediator::RETURNED: $decoder = function ($message) use($that) { $call = shm_get_var($that->shm, $message['call_id']); if ($call && $call->status == $message['status']) { @shm_remove_var($that->shm, $message['call_id']); } return $call; }; break; default: $decoder = function ($message) use($that) { $call = $that->mediator->get_struct($message['call_id']); // If we don't have a local copy of $call the most likely scenario is a --recoverworkers situation. // Create a placeholder. We'll get a full copy of the struct when it's returned from the worker if (!$call) { $call = new Core_Worker_Call($message['call_id']); } $call->status($message['status']); $call->pid = $message['pid']; return $call; }; } // Now get on with decoding the $message $tries = 1; do { $call = $decoder($message); } while (empty($call) && $this->error(null, $tries) && $tries++ < 3); if (!is_object($call)) { throw new Exception(__METHOD__ . " Failed. Could Not Decode Message: " . print_r($message, true)); } if (!$this->memory_allocation_warning && $call->size > $this->memory_allocation / 50) { $this->memory_allocation_warning = true; $suggested_size = $call->size * 60; $this->mediator->log("WARNING: The memory allocated to this worker is too low and may lead to out-of-shared-memory errors.\n" . " Based on this job, the memory allocation should be at least {$suggested_size} bytes. Current allocation: {$this->memory_allocation} bytes."); } return $call; }