で、さっそく問題発声。ギャース。いや発生。
MT4プラグインであるStyleCatcherは、ネットワーク上のレポジトリに公開されているMT用のブログスタイルを取ってきて自分のブログに適用してくれるわけですが、標準のレポジトリ(http://www.sixapart.com/movabletype/styles/mt4/library)にとりにいくと、数が多いせいかかなり待たされます。で、SuiteXのHTTPサーバ(Apacheだよね?)のタイムアウト設定が短めで1分?かそこらに設定されていて、全ての処理が終わりきる前にタイムアウトが起こり、処理が継続できなくなるという事態に陥ってしまったのでした。うはあ。
"Timeout waiting for output from CGI script"てやつですな。
じゃ、一気に全部のスタイルを持ってこようとするのがよくないので、タイムアウトを起こさない程度の少量ずつを取ってくるようにすれば問題ないはずだよねと素朴に変更を加えてみたのが以下の通り。
diff -x mt-config.cgi -ur MT-4.261-ja/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm MT-4.261-ja.new/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm
--- MT-4.261-ja/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm 2009-06-16 14:45:32.000000000 +0900
+++ MT-4.261-ja.new/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm 2009-09-10 01:42:06.000000000 +0900
@@ -138,7 +138,7 @@
my $app = shift;
return $app->json_error( $app->errstr ) unless $app->validate_magic;
- my $data = fetch_themes($app->param('url'))
+ my $data = fetch_themes($app->param('url'), $app->param('offs'), $app->param('count'))
or return $app->json_error( $app->errstr );
return $app->json_result( $data );
}
@@ -449,7 +449,7 @@
# pulls a list of themes available from a particular url
sub fetch_themes {
my $app = MT->app;
- my ($url) = @_;
+ my ($url, $offs, $count) = @_;
return undef unless $url;
my $blog_id = $app->param('blog_id');
@@ -503,6 +503,10 @@
}
push @repo_themes, $css;
}
+ $data->{paginate}{total} = $#repo_themes + 1;
+ $data->{paginate}{offset} = $offs;
+ $data->{paginate}{count} = $count;
+ @repo_themes = splice(@repo_themes, $offs, $count);
my $themes = [];
for my $repo_theme (@repo_themes) {
diff -x mt-config.cgi -ur MT-4.261-ja/plugins/StyleCatcher/tmpl/view.tmpl MT-4.261-ja.new/plugins/StyleCatcher/tmpl/view.tmpl
--- MT-4.261-ja/plugins/StyleCatcher/tmpl/view.tmpl 2009-06-16 14:26:14.000000000 +0900
+++ MT-4.261-ja.new/plugins/StyleCatcher/tmpl/view.tmpl 2009-09-10 02:04:15.000000000 +0900
@@ -393,6 +393,9 @@
}
if (data.result.themes)
loadThemes(data.result.themes, cat);
+ var paginate = data.result.paginate;
+ if (paginate.offset + paginate.count < paginate.total)
+ getStyles(repo_id, data.result.repo['url'], paginate.offset + paginate.count, paginate.count);
}
function createCategory(cat_name, cat_title, url) {
@@ -484,7 +487,7 @@
}
}
- function getStyles(repo_id, url) {
+ function getStyles(repo_id, url, offs, count) {
var btn = getByID("find-button");
TC.addClassName(btn, "hidden");
TC.removeClassName(TC.elementOrId("loading-styles"), "hidden");
@@ -496,6 +499,8 @@
'arguments': {
'__mode': 'stylecatcher_js',
'magic_token': '',
+ 'offs': offs ? offs : 0,
+ 'count': count ? count : 9,
'url': url
}
});
取得中状態の見せ方をもう少しかっこ良くすることもできると思うけど、とりあえずこんなかんじ。流れは以下のようになっちょります。まじで素朴にpaginate。
- ブラウザからサーバへの取得リクエスト時に、「今回のオフセット」と「個数」を追加して送信
- サーバ(CGI)は指定されたオフセットと個数分のみを切り出してブラウザに対して応答
- このとき、応答に「今回のオフセット」と「個数」、さらに「全体の個数」を付加
- サーバの応答を受け取り、ブラウザは表示処理を行う
- 「今回のオフセット」+「個数」=「次回のオフセット」として計算
- 「次回のオフセット」が「全体の個数」を下回れば、「次回のオフセット」と「個数」を用いて次の取得リクエストを送信し、同じ内容を繰り返す。
- 「次回のオフセット」が「全体の個数」を上回るか等しければ、繰り返しを終了。