Ejemplo n.º 1
0
 /**
  * Starts the event loop in the Forked process that will listen for messages
  * Note: Runs only in the worker (forked) process
  * @return void
  */
 public function start()
 {
     // Define automatic restart intervals. We want to add some entropy to avoid having all worker processes
     // in a pool restart at the same time. Use a very crude technique to create a random number along a normal distribution.
     $entropy = round((mt_rand(-1000, 1000) + mt_rand(-1000, 1000) + mt_rand(-1000, 1000)) / 100, 0);
     $recycle = false;
     while (!Core_Daemon::is('parent') && !Core_Daemon::is('shutdown') && !$recycle) {
         // Give the CPU a break - Sleep for 1/20 a second.
         usleep(50000);
         if ($this->auto_restart) {
             $max_jobs = $this->call_count++ >= 25 + $entropy;
             $min_runtime = $this->daemon->runtime() >= 60 * 5;
             $max_runtime = $this->daemon->runtime() >= 60 * 30 + $entropy * 10;
             $recycle = $max_runtime || $min_runtime && $max_jobs;
         }
         if (mt_rand(1, 5) == 1) {
             $this->garbage_collector();
         }
         if ($call = $this->via->get(self::WORKER_CALL, true)) {
             try {
                 // If the current via supports it, calls can be cancelled while they are enqueued
                 if ($call->status == self::CANCELLED) {
                     $this->log("Call {$call->id} Cancelled By Mediator -- Skipping...");
                     continue;
                 }
                 $alias = $this instanceof Core_Worker_ObjectMediator ? $call->method : $this->alias;
                 if (!$this->breakpoint(sprintf('[Call %s] Calling method in worker', $call->id, $alias), $call->id)) {
                     $call->cancelled();
                     continue;
                 }
                 $call->running();
                 if (!$this->via->put($call)) {
                     $this->log("Call {$call->id} Could Not Ack Running.");
                 }
                 $call->returned(call_user_func_array($this->get_callback($call->method), $call->args));
                 if (!$this->via->put($call)) {
                     $this->log("Call {$call->id} Could Not Ack Complete.");
                 }
             } catch (Exception $e) {
                 $this->error($e->getMessage());
             }
         }
     }
     $this->log("Recycling Worker...");
 }