Exemplo n.º 1
0
 public function sieve($start, $end)
 {
     $primes = array();
     // The sieve is designed to work from 3 and above.
     // We know that "2" is a Prime. So if $start is less than "3", we will prepend the array with "2".
     // But in some cases, "1" is considered prime, and in others not. For our purposes, we've put a setting in the ini file to resolve this issue.
     // The daemon() method on the mediator allows us to import objects/properties from the daemon by name
     if ($start < 3) {
         $settings = $this->mediator->daemon('settings');
         if ($start < 1 && $settings['default']['is_one_prime']) {
             $primes = array(1, 2);
         } else {
             $primes = array(2);
         }
         $start = 3;
     }
     // This is an example of how you can add in custom breakpoints that will be active when you run
     // your daemon with the --debugworkers flag set.
     $this->mediator->breakpoint("Something Is Happeneing in sieve! Oh Noes!");
     for ($i = $start; $i <= $end; $i++) {
         if ($i % 2 != 1) {
             continue;
         }
         $d = 3;
         $x = sqrt($i);
         while ($i % $d != 0 && $d < $x) {
             $d += 2;
         }
         if (($i % $d == 0 && $i != $d) * 1 == 0) {
             $primes[] = $i;
         }
     }
     return $primes;
 }
Exemplo n.º 2
0
 /**
  * Poll the API for updated information -- Simulate an API call of varying duration.
  * @param Credential $credential
  * @return void
  * @throws \ConnectionException
  */
 public function poll(Credential $credential)
 {
     $client = new Client($credential, Pdo::createInstance(), new CoreWorkerMediator($this->mediator));
     try {
         while (true) {
             $client->pollMessages();
             $client->sendMessages();
         }
     } catch (\Exception $e) {
         $this->mediator->log("error: " . $e->getMessage() . "\n" . $e->getTraceAsString());
     }
 }
Exemplo n.º 3
0
 public function check_environment(array $errors = array())
 {
     $errors = array();
     if (!is_object($this->object) || !$this->object instanceof Core_IWorker) {
         $errors[] = 'Invalid worker object. Workers must implement Core_IWorker';
     }
     $object_errors = $this->object->check_environment();
     if (is_array($object_errors)) {
         $errors = array_merge($errors, $object_errors);
     }
     return parent::check_environment($errors);
 }
Exemplo n.º 4
0
 /**
  * Poll the API for updated information -- Simulate an API call of varying duration.
  * @return Array    Return associative array of results
  */
 public function poll(array $existing_results)
 {
     static $calls = 0;
     $calls++;
     $this->results = $existing_results;
     $this->mediator->log('Calling API...');
     // Simulate an API call of varying length
     $rand = mt_rand(1, 10);
     switch ($rand) {
         case 1:
             $ttl = 4;
             break;
         case 2:
         case 3:
             $ttl = 8;
             break;
         case 8:
         case 9:
             $ttl = 16;
             break;
         case 10:
             $ttl = 20;
             break;
         default:
             $ttl = 12;
     }
     // Sleep for $ttl seconds to simulate API request time
     sleep($ttl);
     // If this is our first call, create initial results
     if ($calls == 1) {
         $this->results['customers'] = mt_rand(100, 1000);
         $this->results['sales'] = $this->results['customers'] * mt_rand(20, 100);
         return $this->results;
     }
     // Increase the stats in our results array accordingly
     $multiplier = mt_rand(100, 125) / 100;
     $this->results['customers'] = intval($this->results['customers'] * $multiplier);
     $this->results['sales'] = intval($this->results['sales'] * $multiplier);
     return $this->results;
 }
Exemplo n.º 5
0
 /**
  * Handle IPC Errors
  * @param $error
  * @param int $try    Inform error() of repeated failures of the same $error_code
  * @return boolean  Returns true if the operation should be retried.
  */
 public function error($error, $try = 1)
 {
     // Create an array of random, moderate size and verify it can be written to shared memory
     // Return boolean
     $that = $this;
     $test = function () use($that) {
         $arr = array_fill(0, mt_rand(10, 100), mt_rand(1000, 1000 * 1000));
         $key = mt_rand(1000 * 1000, 2000 * 1000);
         @shm_put_var($that->shm, $key, $arr);
         usleep(5000);
         return @shm_get_var($that->shm, $key) == $arr;
     };
     switch ($error) {
         case 0:
             // Success
         // Success
         case 4:
             // System Interrupt
         // System Interrupt
         case MSG_ENOMSG:
             // No message of desired type
             // Ignored Errors
             return true;
             break;
         case MSG_EAGAIN:
             // Temporary Problem, Try Again
             usleep($this->mediator->backoff(20000, $try));
             return true;
             break;
         case 13:
             // Permission Denied
             $this->mediator->count_error('communication');
             $this->mediator->log('Permission Denied: Cannot connect to message queue');
             $this->purge_mq();
             if (Core_Daemon::is('parent')) {
                 usleep($this->mediator->backoff(100000, $try));
             } else {
                 sleep($this->mediator->backoff(3, $try));
             }
             $this->setup_ipc();
             return true;
             break;
         case 22:
             // Invalid Argument
             // Probably because the queue was removed in another process.
         // Invalid Argument
         // Probably because the queue was removed in another process.
         case 43:
             // Identifier Removed
             // A message queue was re-created at this address but the resource identifier we have needs to be re-created
             $this->mediator->count_error('communication');
             if (Core_Daemon::is('parent')) {
                 usleep($this->mediator->backoff(20000, $try));
             } else {
                 sleep($this->mediator->backoff(2, $try));
             }
             $this->setup_ipc();
             return true;
             break;
         case self::ERROR_UNKNOWN:
             // Almost certainly an issue with shared memory
             $this->mediator->log("Shared Memory I/O Error at Address {$this->mediator->guid}.");
             $this->mediator->count_error('corruption');
             // If this is a worker, all we can do is try to re-attach the shared memory.
             // Any corruption or OOM errors will be handled by the parent exclusively.
             if (!Core_Daemon::is('parent')) {
                 sleep($this->mediator->backoff(3, $try));
                 $this->setup_ipc();
                 return true;
             }
             // If this is the parent, do some diagnostic checks and attempt correction.
             usleep($this->mediator->backoff(20000, $try));
             // Test writing to shared memory using an array that should come to a few kilobytes.
             for ($i = 0; $i < 2; $i++) {
                 if ($test()) {
                     return true;
                 }
                 // Re-attach the shared memory and try the diagnostic again
                 $this->setup_ipc();
             }
             $this->mediator->log("IPC DIAG: Re-Connect failed to solve the problem.");
             if (!$this->mediator->daemon->is('parent')) {
                 break;
             }
             // Attempt to re-connect the shared memory
             // See if we can read what's in shared memory and re-write it later
             $items_to_copy = array();
             $items_to_call = array();
             for ($i = 0; $i < $this->mediator->call_count; $i++) {
                 $call = @shm_get_var($this->shm, $i);
                 if (!is_object($call)) {
                     continue;
                 }
                 $cached = $this->mediator->get_struct($i);
                 if (!is_object($cached)) {
                     continue;
                 }
                 if ($cached->status == Core_Worker_Mediator::TIMEOUT) {
                     continue;
                 }
                 if ($cached->status == Core_Worker_Mediator::UNCALLED) {
                     $items_to_call[$i] = $call;
                     continue;
                 }
                 $items_to_copy[$i] = $call;
             }
             $this->mediator->log("IPC DIAG: Preparing to clean SHM and Reconnect...");
             for ($i = 0; $i < 2; $i++) {
                 $this->purge_shm();
                 $this->setup_ipc();
                 if (!empty($items_to_copy)) {
                     foreach ($items_to_copy as $key => $value) {
                         @shm_put_var($this->shm, $key, $value);
                     }
                 }
                 if (!$test()) {
                     if (empty($items_to_copy)) {
                         $this->mediator->fatal_error("Shared Memory Failure: Unable to proceed.");
                     } else {
                         $this->mediator->log('IPC DIAG: Purging items from shared memory: ' . implode(', ', array_keys($items_to_copy)));
                         unset($items_to_copy);
                     }
                 }
             }
             foreach ($items_to_call as $call) {
                 $this->mediator->retry($call);
             }
             return true;
         default:
             if ($error) {
                 $this->mediator->log("Message Queue Error {$error}: " . posix_strerror($error));
             }
             if (Core_Daemon::is('parent')) {
                 usleep($this->mediator->backoff(100000, $try));
             } else {
                 sleep($this->mediator->backoff(3, $try));
             }
             $this->mediator->count_error('catchall');
             $this->setup_ipc();
             return false;
     }
 }