Esempio n. 1
0
 public static function merge(BloomCache $bcache, $domain, $virtualKey, array $status)
 {
     $limit = 1000;
     $dbr = wfGetDB(DB_SLAVE, array(), $domain);
     $res = $dbr->select('logging', array('log_namespace', 'log_title', 'log_id', 'log_timestamp'), array('log_id > ' . $dbr->addQuotes((int) $status['lastID'])), __METHOD__, array('ORDER BY' => 'log_id', 'LIMIT' => $limit));
     $updates = array();
     if ($res->numRows() > 0) {
         $members = array();
         foreach ($res as $row) {
             $members[] = "{$virtualKey}:{$row->log_namespace}:{$row->log_title}";
         }
         $lastID = $row->log_id;
         $lastTime = $row->log_timestamp;
         if (!$bcache->add('shared', $members)) {
             return false;
         }
         $updates['lastID'] = $lastID;
         $updates['asOfTime'] = wfTimestamp(TS_UNIX, $lastTime);
     } else {
         $updates['asOfTime'] = microtime(true);
     }
     $updates['epoch'] = $status['epoch'] ?: microtime(true);
     $bcache->setStatus($virtualKey, $updates);
     return $updates;
 }
Esempio n. 2
0
 public function execute()
 {
     $type = $this->getOption('filter');
     $domain = $this->getOption('domain');
     $bcache = BloomCache::get($this->getOption('cache'));
     $delay = $this->getOption('delay', 100000.0);
     if (!method_exists("BloomFilter{$type}", 'merge')) {
         $this->error("No \"BloomFilter{$type}::merge\" method found.", 1);
     }
     $virtualKey = "{$domain}:{$type}";
     $status = $bcache->getStatus($virtualKey);
     if ($status == false) {
         $this->error("Could not query virtual bloom filter '{$virtualKey}'.", 1);
     }
     $startTime = microtime(true);
     $this->output("Current timestamp is '{$startTime}'.\n");
     $this->output("Current filter timestamp is '{$status['asOfTime']}'.\n");
     do {
         $status = call_user_func_array(array("BloomFilter{$type}", 'merge'), array($bcache, $domain, $virtualKey, $status));
         if ($status == false) {
             $this->error("Could not query virtual bloom filter '{$virtualKey}'.", 1);
         }
         $this->output("Filter updated to timestamp '{$status['asOfTime']}'.\n");
         usleep($delay);
     } while ($status['asOfTime'] && $status['asOfTime'] < $startTime);
     $this->output("Done, filter {$type} of domain {$domain} reached time '{$startTime}'.\n");
 }
 protected function tearDown()
 {
     parent::tearDown();
     $fcache = BloomCache::get('main');
     if ($fcache instanceof BloomCacheRedis) {
         $fcache->delete("unit-testing-" . self::$suffix);
     }
 }
 /**
  * @params include:
  *   - redisServers : list of servers (address:<port>) (the first is the master)
  *   - redisConf    : additional redis configuration
  *
  * @param array $config
  */
 public function __construct(array $config)
 {
     parent::__construct($config);
     $redisConf = $config['redisConfig'];
     $redisConf['serializer'] = 'none';
     // manage that in this class
     $this->redisPool = RedisConnectionPool::singleton($redisConf);
     $this->servers = $config['redisServers'];
     $this->lockMgr = new RedisLockManager(array('lockServers' => array('srv1' => $this->servers[0]), 'srvsByBucket' => array(0 => array('srv1')), 'redisConfig' => $config['redisConfig']));
 }
Esempio n. 5
0
 public function __construct(array $config)
 {
     parent::__construct(array('cacheId' => 'none'));
 }
Esempio n. 6
0
 /**
  * Show the error text for a missing article. For articles in the MediaWiki
  * namespace, show the default message text. To be called from Article::view().
  */
 public function showMissingArticle()
 {
     global $wgSend404Code;
     $outputPage = $this->getContext()->getOutput();
     // Whether the page is a root user page of an existing user (but not a subpage)
     $validUserPage = false;
     $title = $this->getTitle();
     # Show info in user (talk) namespace. Does the user exist? Is he blocked?
     if ($title->getNamespace() == NS_USER || $title->getNamespace() == NS_USER_TALK) {
         $parts = explode('/', $title->getText());
         $rootPart = $parts[0];
         $user = User::newFromName($rootPart, false);
         $ip = User::isIP($rootPart);
         $block = Block::newFromTarget($user, $user);
         if (!($user && $user->isLoggedIn()) && !$ip) {
             # User does not exist
             $outputPage->wrapWikiMsg("<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>", array('userpage-userdoesnotexist-view', wfEscapeWikiText($rootPart)));
         } elseif (!is_null($block) && $block->getType() != Block::TYPE_AUTO) {
             # Show log extract if the user is currently blocked
             LogEventsList::showLogExtract($outputPage, 'block', MWNamespace::getCanonicalName(NS_USER) . ':' . $block->getTarget(), '', array('lim' => 1, 'showIfEmpty' => false, 'msgKey' => array('blocked-notice-logextract', $user->getName())));
             $validUserPage = !$title->isSubpage();
         } else {
             $validUserPage = !$title->isSubpage();
         }
     }
     wfRunHooks('ShowMissingArticle', array($this));
     // Give extensions a chance to hide their (unrelated) log entries
     $logTypes = array('delete', 'move');
     $conds = array("log_action != 'revision'");
     wfRunHooks('Article::MissingArticleConditions', array(&$conds, $logTypes));
     # Show delete and move logs
     $member = $title->getNamespace() . ':' . $title->getDBkey();
     // @todo: move optimization to showLogExtract()?
     if (BloomCache::get('main')->check(wfWikiId(), 'TitleHasLogs', $member)) {
         LogEventsList::showLogExtract($outputPage, $logTypes, $title, '', array('lim' => 10, 'conds' => $conds, 'showIfEmpty' => false, 'msgKey' => array('moveddeleted-notice')));
     }
     if (!$this->mPage->hasViewableContent() && $wgSend404Code && !$validUserPage) {
         // If there's no backing content, send a 404 Not Found
         // for better machine handling of broken links.
         $this->getContext()->getRequest()->response()->header("HTTP/1.1 404 Not Found");
     }
     // Also apply the robot policy for nonexisting pages (even if a 404 was used for sanity)
     $policy = $this->getRobotPolicy('view');
     $outputPage->setIndexPolicy($policy['index']);
     $outputPage->setFollowPolicy($policy['follow']);
     $hookResult = wfRunHooks('BeforeDisplayNoArticleText', array($this));
     if (!$hookResult) {
         return;
     }
     # Show error message
     $oldid = $this->getOldID();
     if ($oldid) {
         $text = wfMessage('missing-revision', $oldid)->plain();
     } elseif ($title->getNamespace() === NS_MEDIAWIKI) {
         // Use the default message text
         $text = $title->getDefaultMessageText();
     } elseif ($title->quickUserCan('create', $this->getContext()->getUser()) && $title->quickUserCan('edit', $this->getContext()->getUser())) {
         $message = $this->getContext()->getUser()->isLoggedIn() ? 'noarticletext' : 'noarticletextanon';
         $text = wfMessage($message)->plain();
     } else {
         $text = wfMessage('noarticletext-nopermission')->plain();
     }
     $text = "<div class='noarticletext'>\n{$text}\n</div>";
     $outputPage->addWikiText($text);
 }
Esempio n. 7
0
 /**
  * Inserts the entry into the logging table.
  * @param IDatabase $dbw
  * @return int ID of the log entry
  * @throws MWException
  */
 public function insert(IDatabase $dbw = null)
 {
     global $wgContLang;
     $dbw = $dbw ?: wfGetDB(DB_MASTER);
     $id = $dbw->nextSequenceValue('logging_log_id_seq');
     if ($this->timestamp === null) {
         $this->timestamp = wfTimestampNow();
     }
     # Trim spaces on user supplied text
     $comment = trim($this->getComment());
     # Truncate for whole multibyte characters.
     $comment = $wgContLang->truncate($comment, 255);
     $data = array('log_id' => $id, 'log_type' => $this->getType(), 'log_action' => $this->getSubtype(), 'log_timestamp' => $dbw->timestamp($this->getTimestamp()), 'log_user' => $this->getPerformer()->getId(), 'log_user_text' => $this->getPerformer()->getName(), 'log_namespace' => $this->getTarget()->getNamespace(), 'log_title' => $this->getTarget()->getDBkey(), 'log_page' => $this->getTarget()->getArticleID(), 'log_comment' => $comment, 'log_params' => serialize((array) $this->getParameters()));
     if (isset($this->deleted)) {
         $data['log_deleted'] = $this->deleted;
     }
     $dbw->insert('logging', $data, __METHOD__);
     $this->id = !is_null($id) ? $id : $dbw->insertId();
     $rows = array();
     foreach ($this->relations as $tag => $values) {
         if (!strlen($tag)) {
             throw new MWException("Got empty log search tag.");
         }
         if (!is_array($values)) {
             $values = array($values);
         }
         foreach ($values as $value) {
             $rows[] = array('ls_field' => $tag, 'ls_value' => $value, 'ls_log_id' => $this->id);
         }
     }
     if (count($rows)) {
         $dbw->insert('log_search', $rows, __METHOD__, 'IGNORE');
     }
     // Update any bloom filter cache
     $member = $this->getTarget()->getNamespace() . ':' . $this->getTarget()->getDBkey();
     BloomCache::get('main')->insert(wfWikiId(), 'TitleHasLogs', $member);
     return $this->id;
 }