Example #1
0
 public static function store(AppNotice $notice)
 {
     $binary_notification = $notice->serialize();
     $config = Config::instance();
     $tube = Config::instance()->queuePrefix() . self::SEP . $notice->getApp() . self::SEP . date('Ymd', Time::now());
     $try = $config->retries() + 1;
     $conns = $config->connections();
     $keys = array_keys($conns);
     shuffle($keys);
     $ttr = 30;
     // $config->ttr();
     $priority = 0;
     //floor( $notice->getExpires() - time::now() / 3600 );
     $delay = 0;
     foreach ($keys as $key) {
         $conn = $conns[$key];
         if (!$try--) {
             break;
         }
         $res = $conn->putInTube($tube, $binary_notification, $priority, $delay, $ttr);
         if (!$res) {
             continue;
         }
         return $conn->hostInfo() . '-' . $res;
     }
     throw new Exception('storage error', $conns);
 }
 /**
  * populate notices into the system.
  * @return boolean
  */
 public function populate()
 {
     try {
         $streams = $this->pool->streams();
         if (!$this->active && !$streams) {
             return TRUE;
         }
         if ($this->limit && $this->processed >= $this->limit) {
             return $this->shutdown();
         }
         $queue_bytes = 0;
         $block_patterns = array();
         shuffle($streams);
         foreach ($streams as $stream) {
             if (strlen($stream->out) > $this->max_bytes) {
                 $block_patterns[$stream->app] = $stream->app;
             }
         }
         $free_bytes = $this->max_bytes - $queue_bytes;
         if ($this->active && $free_bytes > 0) {
             $ct = 0;
             $config = Config::instance();
             $conns = $config->connections();
             $keys = array_keys($conns);
             shuffle($keys);
             $allow = $this->buildAllow($block_patterns);
             foreach ($keys as $key) {
                 $conn = $conns[$key];
                 if (!$this->syncWatch($conn, $allow)) {
                     continue;
                 }
                 $change_watch = FALSE;
                 while ($res = $conn->reserve(0)) {
                     $this->debug($res);
                     if (!$this->syncWatch($conn, $allow)) {
                         continue 2;
                     }
                     $change_watch = FALSE;
                     try {
                         $notice = new AppNotice($res->getData());
                     } catch (Exception $e) {
                         $this->invalid++;
                         if ($this->debug) {
                             $this->debug($e, E_WARNING);
                         }
                         $conn->delete($res);
                         continue;
                     }
                     if (!$notice->getDeviceToken() || !$notice->getApp()) {
                         $this->invalid++;
                         if ($this->debug) {
                             $this->debug(new Exception('invalid notice', $notice), E_WARNING);
                         }
                         $conn->delete($res);
                         continue;
                     }
                     $stream = $this->connection($notice->getApp());
                     $stream->out .= $notice->core()->serialize();
                     if ($this->debug) {
                         $this->debug($notice, E_NOTICE);
                     }
                     $this->processed++;
                     $ct++;
                     $conn->delete($res);
                     if (strlen($stream->out) > $this->max_bytes) {
                         $block_patterns[$stream->app] = $stream->app;
                         $change_watch = TRUE;
                     }
                     if ($this->limit && $this->processed >= $this->limit) {
                         break 2;
                     }
                 }
             }
             if ($this->debug && $ct > 0) {
                 $this->debug("notices dequeued: {$ct}", E_NOTICE);
             }
             if ($ct < 1) {
                 $pending = FALSE;
                 foreach ($this->pool->streams() as $stream) {
                     if ($stream->out) {
                         $pending = TRUE;
                         break;
                     }
                 }
                 if (!$pending) {
                     if ($this->debug) {
                         $this->debug("nothing to process. waiting ...", E_NOTICE);
                     }
                     sleep(1);
                 }
             }
         }
         return TRUE;
     } catch (\Exception $e) {
         $this->debug($e, E_WARNING);
         return FALSE;
     }
 }