From 5ddd7c9677b644396981de7df8176a3b168ffe21 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 21 Feb 2010 20:04:06 -0800 Subject: Fix Kohana's internal cache for Gallery's usage pattern. Adds a core.internal_cache_read_only config variable to Kohana's internals. Kohana's internal_cache for find_file wasn't working in Gallery because the cache would be emptied on each request after reading it from disk and before most lookups would run. 1. Bootstrap sets initial core.modules (= include path): forge, kohana23_compat, gallery. 2. Kohana::setup() loads find_file cache from disk. 3. Gallery loads list of active modules and themes, and updates the core.modules value (=include path), which forces the internal find_file cache to be empties (which makes sense). 4. Request processing starts, and thus 80% of all Kohana::find_file() triggered is_file() invocations start off with an empty find_file cache. In the case of my small Gallery installation, we're talking about 3100 is_file() invocations per request with or without internal_cache enabled. With this fix, this number is down to 800 invocations. The basic idea is that we treat the cache as read only and don't write any (possibly dirty) values to it in memory until we're sure that the include path won't change later on in the request processing. Once we know the list of active modules and themes, we can update core.modules and finally flip the read-only state of the cache and start writing to it. --- modules/gallery/helpers/gallery_event.php | 1 + 1 file changed, 1 insertion(+) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 36f91142..a6783bc6 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -25,6 +25,7 @@ class gallery_event_Core { static function gallery_ready() { identity::load_user(); theme::load_themes(); + Kohana_Config::instance()->set('core.internal_cache_read_only', false); locales::set_request_locale(); } -- cgit v1.2.3 From 6cbe0f78aa80a2810908a76ca163f1dfff2f0726 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 21 Feb 2010 21:07:55 -0800 Subject: Revert "Fix Kohana's internal cache for Gallery's usage pattern." This reverts commit 5ddd7c9677b644396981de7df8176a3b168ffe21. --- application/config/config.php | 6 ---- modules/gallery/helpers/gallery_event.php | 1 - system/core/Kohana.php | 47 +++++++++++-------------------- 3 files changed, 17 insertions(+), 37 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/application/config/config.php b/application/config/config.php index 1c5bccb7..aecc400c 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -67,12 +67,6 @@ $config["url_suffix"] = ""; * can give significant speed improvements at the expense of delayed updating. */ $config["internal_cache"] = FALSE; -/** - * Enable or disable writing to the internal cache. Used by Gallery to treat - * the cache as read-only until all active modules and themes are in the - * include path. - */ -$config["internal_cache_read_only"] = TRUE; $config["internal_cache_path"] = VARPATH . "tmp/"; /** diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index a6783bc6..36f91142 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -25,7 +25,6 @@ class gallery_event_Core { static function gallery_ready() { identity::load_user(); theme::load_themes(); - Kohana_Config::instance()->set('core.internal_cache_read_only', false); locales::set_request_locale(); } diff --git a/system/core/Kohana.php b/system/core/Kohana.php index 1ed6d725..ae056d0e 100644 --- a/system/core/Kohana.php +++ b/system/core/Kohana.php @@ -365,17 +365,13 @@ abstract class Kohana_Core { // Add SYSPATH as the last path Kohana::$include_paths[] = SYSPATH; - if ( ! Kohana::config('core.internal_cache_read_only')) + // Clear cached include paths + self::$internal_cache['find_file_paths'] = array(); + if ( ! isset(self::$write_cache['find_file_paths'])) { - // Clear cached include paths - self::$internal_cache['find_file_paths'] = array(); - - if ( ! isset(self::$write_cache['find_file_paths'])) - { - // Write cache at shutdown - self::$write_cache['find_file_paths'] = TRUE; - } - } + // Write cache at shutdown + self::$write_cache['find_file_paths'] = TRUE; + } } @@ -822,17 +818,13 @@ abstract class Kohana_Core { } } - if ( ! Kohana::config('core.internal_cache_read_only')) + if ( ! isset(Kohana::$write_cache['find_file_paths'])) { - Kohana::$internal_cache['find_file_paths'][$search] = $found; - - if ( ! isset(Kohana::$write_cache['find_file_paths'])) - { - // Write cache at shutdown - Kohana::$write_cache['find_file_paths'] = TRUE; - } + // Write cache at shutdown + Kohana::$write_cache['find_file_paths'] = TRUE; } - return $found; + + return Kohana::$internal_cache['find_file_paths'][$search] = $found; } /** @@ -908,7 +900,8 @@ abstract class Kohana_Core { public static function message($key, $args = array()) { // Extract the main group from the key - list ($group, $subkey) = explode('.', $key, 2); + $group = explode('.', $key, 2); + $group = $group[0]; if ( ! isset(Kohana::$internal_cache['messages'][$group])) { @@ -920,23 +913,17 @@ abstract class Kohana_Core { include $file[0]; } - if ( ! isset(Kohana::$write_cache['messages']) && ! Kohana::config('core.internal_cache_read_only')) + if ( ! isset(Kohana::$write_cache['messages'])) { // Write language cache Kohana::$write_cache['messages'] = TRUE; } - if ( ! Kohana::config('core.internal_cache_read_only')) - { - Kohana::$internal_cache['messages'][$group] = $messages; - } - } - else - { - $messages = Kohana::$internal_cache['messages'][$group]; + + Kohana::$internal_cache['messages'][$group] = $messages; } // Get the line from cache - $line = Kohana::key_string($messages, $subkey); + $line = Kohana::key_string(Kohana::$internal_cache['messages'], $key); if ($line === NULL) { -- cgit v1.2.3 From 334cd2368de24a76cd49681a14295350e85714d0 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 21 Feb 2010 23:50:01 -0800 Subject: Performance improvement: Load all translations of a locale as one serialized array from the Cache. Until now, we loaded hundreds of translation messages row by row, and unserializing one by one at bootstrap time. That amounted to a significant percentage of the complete request time. This approach is more than 10x faster. --- modules/gallery/controllers/l10n_client.php | 2 ++ modules/gallery/helpers/gallery_task.php | 2 ++ modules/gallery/libraries/Gallery_I18n.php | 45 ++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 13 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/l10n_client.php b/modules/gallery/controllers/l10n_client.php index e20bab50..be0aaa11 100644 --- a/modules/gallery/controllers/l10n_client.php +++ b/modules/gallery/controllers/l10n_client.php @@ -80,6 +80,8 @@ class L10n_Client_Controller extends Controller { $entry->save(); + Gallery_I18n::clear_cache($locale); + print json_encode(new stdClass()); } diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index 3e6278e5..617f7f48 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -201,6 +201,8 @@ class gallery_task_Core { $total = $num_fetched + $num_remaining; $task->percent_complete = 70 + 30 * ((float) $num_fetched / $total); } else { + Gallery_I18n::clear_cache(); + $task->done = true; $task->state = "success"; $task->status = t("Translations installed/updated"); diff --git a/modules/gallery/libraries/Gallery_I18n.php b/modules/gallery/libraries/Gallery_I18n.php index ac0588e3..0e9c0bdc 100644 --- a/modules/gallery/libraries/Gallery_I18n.php +++ b/modules/gallery/libraries/Gallery_I18n.php @@ -150,33 +150,43 @@ class Gallery_I18n_Core { private function lookup($locale, $message) { if (!isset($this->_cache[$locale])) { - $this->_cache[$locale] = array(); - // TODO: Load data from locale file instead of the DB. + $this->_cache[$locale] = self::load_translations($locale); + } + + $key = self::get_message_key($message); + + if (isset($this->_cache[$locale][$key])) { + return $this->_cache[$locale][$key]; + } else { + return null; + } + } + + private static function load_translations($locale) { + $cache_key = "translation|" . $locale; + $cache = Cache::instance(); + $translations = $cache->get($cache_key); + if (empty($translations)) { foreach (db::build() ->select("key", "translation") ->from("incoming_translations") ->where("locale", "=", $locale) ->execute() as $row) { - $this->_cache[$locale][$row->key] = unserialize($row->translation); + $translations[$row->key] = unserialize($row->translation); } - + // Override incoming with outgoing... foreach (db::build() ->select("key", "translation") ->from("outgoing_translations") ->where("locale", "=", $locale) ->execute() as $row) { - $this->_cache[$locale][$row->key] = unserialize($row->translation); + $translations[$row->key] = unserialize($row->translation); } + + $cache->set($cache_key, $translations, array("translation"), 0); } - - $key = self::get_message_key($message); - - if (isset($this->_cache[$locale][$key])) { - return $this->_cache[$locale][$key]; - } else { - return null; - } + return $translations; } public function has_translation($message, $options=null) { @@ -256,6 +266,15 @@ class Gallery_I18n_Core { return $this->_call_log; } + public static function clear_cache($locale=null) { + $cache = Cache::instance(); + if ($locale) { + $cache->delete("translation|" . $locale); + } else { + $cache->delete_tag("translation"); + } + } + private static function get_plural_key($locale, $count) { $parts = explode('_', $locale); $language = $parts[0]; -- cgit v1.2.3 From 6ce01328422cc587dedf555d0ba3eb8a0ee05a9f Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Mon, 22 Feb 2010 00:30:54 -0800 Subject: Fix for ticket #1027: Add index on cache key column. (and fix the packager to truncate the cache table before packaging) --- installer/install.sql | 3 ++- modules/gallery/controllers/packager.php | 1 + modules/gallery/helpers/gallery_installer.php | 12 +++++++++++- modules/gallery/module.info | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/installer/install.sql b/installer/install.sql index 28a9caa5..ebe3651d 100644 --- a/installer/install.sql +++ b/installer/install.sql @@ -42,6 +42,7 @@ CREATE TABLE {caches} ( `expiration` int(9) NOT NULL, `cache` longblob, PRIMARY KEY (`id`), + KEY `key` (`key`), KEY `tags` (`tags`) ) DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; @@ -239,7 +240,7 @@ CREATE TABLE {modules} ( UNIQUE KEY `name` (`name`) ) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; -INSERT INTO {modules} VALUES (1,1,'gallery',29); +INSERT INTO {modules} VALUES (1,1,'gallery',30); INSERT INTO {modules} VALUES (2,1,'user',3); INSERT INTO {modules} VALUES (3,1,'comment',2); INSERT INTO {modules} VALUES (4,1,'organize',1); diff --git a/modules/gallery/controllers/packager.php b/modules/gallery/controllers/packager.php index 66626483..aef032a0 100644 --- a/modules/gallery/controllers/packager.php +++ b/modules/gallery/controllers/packager.php @@ -82,6 +82,7 @@ class Packager_Controller extends Controller { module::set_var("gallery", "blocks_{$key}", serialize($blocks)); } + Database::instance()->query("TRUNCATE {caches}"); Database::instance()->query("TRUNCATE {sessions}"); Database::instance()->query("TRUNCATE {logs}"); db::build() diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index b594ddcf..6f8a6688 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -32,6 +32,10 @@ class gallery_installer { PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;"); + // Using a simple index instead of a unique key for the + // key column to avoid handling of concurrency issues + // on insert. Thus allowing concurrent inserts on the + // same cache key, as does Memcache / xcache. $db->query("CREATE TABLE {caches} ( `id` int(9) NOT NULL auto_increment, `key` varchar(255) NOT NULL, @@ -39,6 +43,7 @@ class gallery_installer { `expiration` int(9) NOT NULL, `cache` longblob, PRIMARY KEY (`id`), + KEY (`key`), KEY (`tags`)) DEFAULT CHARSET=utf8;"); @@ -290,7 +295,7 @@ class gallery_installer { module::set_var("gallery", "credits", (string) $powered_by_string); module::set_var("gallery", "simultaneous_upload_limit", 5); module::set_var("gallery", "admin_area_timeout", 90 * 60); - module::set_version("gallery", 29); + module::set_version("gallery", 30); } static function upgrade($version) { @@ -545,6 +550,11 @@ class gallery_installer { module::set_var("gallery", "credits", "Powered by %gallery_version"); module::set_version("gallery", $version = 29); } + + if ($version == 29) { + $db->query("ALTER TABLE {caches} ADD KEY (`key`);"); + module::set_version("gallery", $version = 30); + } } static function uninstall() { diff --git a/modules/gallery/module.info b/modules/gallery/module.info index 39615e1c..df2be978 100644 --- a/modules/gallery/module.info +++ b/modules/gallery/module.info @@ -1,3 +1,3 @@ name = "Gallery 3" description = "Gallery core application" -version = 29 +version = 30 -- cgit v1.2.3 From fb5503be09047def6efd24a74188ad55af7a80f2 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 23 Feb 2010 11:10:32 -0800 Subject: Name this release "Santa Fe". Fixes ticket #683. --- modules/gallery/helpers/gallery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php index 84f8a7fb..a43b180b 100644 --- a/modules/gallery/helpers/gallery.php +++ b/modules/gallery/helpers/gallery.php @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class gallery_Core { - const VERSION = "3.0 git (pre-RC1)"; + const VERSION = "3.0 RC1 (Santa Fe)"; /** * If Gallery is in maintenance mode, then force all non-admins to get routed to a "This site is -- cgit v1.2.3 From c38bee203b8e89cfb1446ecacd133f3c679ffbcc Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Wed, 24 Feb 2010 16:21:54 -0800 Subject: Add Faroese to the language list. Verified that it uses the default plural rules, thus no changes in Gallery_I18n.php or on the server side required. --- modules/gallery/helpers/locales.php | 1 + 1 file changed, 1 insertion(+) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php index e72d7ed9..62b08fb9 100644 --- a/modules/gallery/helpers/locales.php +++ b/modules/gallery/helpers/locales.php @@ -81,6 +81,7 @@ class locales_Core { $l["eu_ES"] = "Euskara"; // Basque $l["fa_IR"] = "فارس"; // Farsi $l["fi_FI"] = "Suomi"; // Finnish + $l["fo_FO"] = "Føroyskt"; // Faroese $l["fr_FR"] = "Français"; // French $l["ga_IE"] = "Gaeilge"; // Irish $l["he_IL"] = "עברית"; // Hebrew -- cgit v1.2.3