/** * Important: YOU HAVE TO make sure $tables and $where_conds don't contain * unescaped user-supplied data! */ public static function get_set($tables, $joins, $where_conds, $min_store, $ref_max_age) { # Compute the "params hash". $params_hash = md5(serialize(array($tables, $joins, $where_conds))); # Check if there exists an entry for this hash, which also meets the # given freshness criteria. list($set_id, $date_created, $expires) = self::find_param_set($params_hash, $ref_max_age); if ($set_id === null) { # To avoid generating the same results by multiple threads at once # (the "tile" method uses the "save" method, so the problem is # quite real!), we will acquire a write-lock here. $lock = OkapiLock::get("search-results-writer"); $lock->acquire(); try { # Make sure we were the first to acquire the lock. list($set_id, $date_created, $expires) = self::find_param_set($params_hash, $ref_max_age); if ($set_id === null) { # We are in the first thread which have acquired the lock. # We will proceed with result-set creation. Other threads # will be waiting until we finish. Db::execute("\n insert into okapi_search_sets (params_hash, date_created, expires)\n values (\n 'processing in progress',\n now(),\n date_add(now(), interval '" . mysql_real_escape_string($min_store + 60) . "' second)\n )\n "); $set_id = Db::last_insert_id(); $date_created = time(); $expires = $date_created + $min_store + 60; Db::execute("\n insert into okapi_search_results (set_id, cache_id)\n select distinct\n '" . mysql_real_escape_string($set_id) . "',\n caches.cache_id\n from\n " . implode(", ", $tables) . "\n " . implode(" ", $joins) . "\n where (" . implode(") and (", $where_conds) . ")\n "); # Lock barrier, to make sure the data is visible by other # sessions. See http://bugs.mysql.com/bug.php?id=36618 Db::execute("lock table okapi_search_results write"); Db::execute("unlock tables"); Db::execute("\n update okapi_search_sets\n set params_hash = '" . mysql_real_escape_string($params_hash) . "'\n where id = '" . mysql_real_escape_string($set_id) . "'\n "); } else { # Some other thread acquired the lock before us and it has # generated the result set. We don't need to do anything. } $lock->release(); } catch (Exception $e) { # SQL error? Make sure the lock is released and rethrow. $lock->release(); throw $e; } } # If we got an old set, we may need to expand its lifetime in order to # meet user's "min_store" criterium. if (time() + $min_store > $expires) { Db::execute("\n update okapi_search_sets\n set expires = date_add(now(), interval '" . mysql_real_escape_string($min_store + 60) . "' second)\n where id = '" . mysql_real_escape_string($set_id) . "'\n "); } return array('set_id' => "{$set_id}", 'generated_at' => date('c', $date_created), 'expires' => date('c', $expires)); }
/** * Reset the schedule of a specified cronjob. This will force the job to * run on nearest occasion (but not NOW). */ public static function reset_job_schedule($job_name) { $thejob = null; foreach (self::get_enabled_cronjobs() as $tmp) { if ($tmp->get_name() == $job_name || $tmp->get_name() == "okapi\\cronjobs\\" . $job_name) { $thejob = $tmp; } } if ($thejob == null) { throw new Exception("Could not reset schedule for job {$job_name}. {$jon_name} not found."); } # We have to acquire lock on the schedule. This might take some time if cron-5 jobs are # currently being run. $type = $thejob->get_type(); $lock = OkapiLock::get('cronjobs-' . $type); $lock->acquire(); $schedule = Cache::get("cron_schedule"); if ($schedule != null) { if (isset($schedule[$thejob->get_name()])) { unset($schedule[$thejob->get_name()]); } Cache::set("cron_schedule", $schedule, 30 * 86400); } $lock->release(); }
private static function ver68() { # Once again, remove unused locks. for ($z = 0; $z <= 21; $z++) { foreach (array("", "-0", "-1") as $suffix) { $lockname = "tile-{$z}{$suffix}"; if (OkapiLock::exists($lockname)) { OkapiLock::get($lockname)->remove(); } } } }