/** * This function is meant to be called **hourly** by cron. * It calls all registred handlers and it also takes care of emitting trigger * signals for longer periods of time than on hourly basis (daily, weekly, ...). * * @param \DateTime forced date time (for testing purposes only) */ public static function run(\DateTime $now = null) { try { Nette\Utils\CriticalSection::enter(); } catch (Nette\InvalidStateException $e) { if ($e->getMessage() == 'Critical section has already been entered.') { throw new CronException('Cron job is already running'); } else { throw $e; } } try { $cache = static::getCache(); if ($now === null) { $now = new \DateTime('now'); } // Hodinova volani ======================================================= if (isset($cache['lastHourly'])) { // Pocet minut od posledni zmeny $offset = (intval($now->format('U')) - intval($cache['lastHourly']->format('U'))) / 60; if ($offset < 1) { throw new CronException('Invalid time offset. Current date is earlier than already processed.'); } if ($offset < 60) { throw new CronException('Invalid time offset. Method was called too early. Probably because of clock skew.'); } } else { $cache['lastHourly'] = null; } self::hourly($cache['lastHourly'], $now); $cache['lastHourly'] = clone $now; // Denni a mesicni volani ================================================ if (intval($now->format('H')) == 0) { self::daily(isset($cache['lastDaily']) ? $cache['lastHourly'] : null, $now); $cache['lastDaily'] = clone $now; if (intval($now->format('d')) == 1) { self::monthly(isset($cache['lastMonthly']) ? $cache['lastMonthly'] : null, $now); $cache['lastMonthly'] = clone $now; } } Nette\Utils\CriticalSection::leave(); } catch (\Exception $e) { Nette\Utils\CriticalSection::leave(); throw $e; } }
/** * Writes item into the cache. * Dependencies are: * - Cache::PRIORITY => (int) priority * - Cache::EXPIRATION => (timestamp) expiration * - Cache::SLIDING => (bool) use sliding expiration? * - Cache::TAGS => (array) tags * - Cache::FILES => (array|string) file names * - Cache::ITEMS => (array|string) cache items * - Cache::CONSTS => (array|string) cache items * * @param mixed key * @param mixed value * @param array dependencies * @return mixed value itself * @throws Nette\InvalidArgumentException */ public function save($key, $data, array $dp = NULL) { $this->key = is_scalar($key) ? (string) $key : serialize($key); $key = $this->namespace . md5($this->key); // convert expire into relative amount of seconds if (isset($dp[Cache::EXPIRATION])) { $dp[Cache::EXPIRATION] = Nette\DateTime::from($dp[Cache::EXPIRATION])->format('U') - time(); } // convert FILES into CALLBACKS if (isset($dp[self::FILES])) { //clearstatcache(); foreach ((array) $dp[self::FILES] as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); // @ - stat may fail } unset($dp[self::FILES]); } // add namespaces to items if (isset($dp[self::ITEMS])) { $dp[self::ITEMS] = (array) $dp[self::ITEMS]; foreach ($dp[self::ITEMS] as $k => $item) { $dp[self::ITEMS][$k] = $this->namespace . md5(is_scalar($item) ? $item : serialize($item)); } } // convert CONSTS into CALLBACKS if (isset($dp[self::CONSTS])) { foreach ((array) $dp[self::CONSTS] as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item)); } unset($dp[self::CONSTS]); } if ($data instanceof Nette\Callback || $data instanceof \Closure) { Nette\Utils\CriticalSection::enter(); $data = $data->__invoke(); Nette\Utils\CriticalSection::leave(); } if (is_object($data)) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data), Nette\Reflection\ClassType::from($data)->getAnnotation('serializationVersion')); } $this->data = $data; if ($data === NULL) { $this->storage->remove($key); } else { $this->storage->write($key, $data, (array) $dp); } return $data; }
function save($key, $data, array $dp = NULL) { $this->release(); $key = $this->namespace . md5(is_scalar($key) ? $key : serialize($key)); if ($data instanceof Nette\Callback || $data instanceof \Closure) { Nette\Utils\CriticalSection::enter(); $data = $data->__invoke(); Nette\Utils\CriticalSection::leave(); } if ($data === NULL) { return $this->storage->remove($key); } elseif (is_object($data)) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data), Nette\Reflection\ClassType::from($data)->getAnnotation('serializationVersion')); } if (isset($dp[Cache::EXPIRATION])) { $dp[Cache::EXPIRATION] = Nette\DateTime::from($dp[Cache::EXPIRATION])->format('U') - time(); } if (isset($dp[self::FILES])) { foreach (array_unique((array) $dp[self::FILES]) as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); } unset($dp[self::FILES]); } if (isset($dp[self::ITEMS])) { $dp[self::ITEMS] = array_unique((array) $dp[self::ITEMS]); foreach ($dp[self::ITEMS] as $k => $item) { $dp[self::ITEMS][$k] = $this->namespace . md5(is_scalar($item) ? $item : serialize($item)); } } if (isset($dp[self::CONSTS])) { foreach (array_unique((array) $dp[self::CONSTS]) as $item) { $dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item)); } unset($dp[self::CONSTS]); } $this->storage->write($key, $data, (array) $dp); return $data; }