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; } }