attach プラグインの md5 計算、mimetypeのチェックによる負荷の問題

修正

メッセージ

attach プラグインはファイル情報を取得すると自動的に md5 でのハッシュ計算を行います。そのため、添付ファイルのサイズ、数によっては、添付ファイルの情報を含むページの表示に時間を要し、その間 cpu を消費し続けます。これは、使い勝手についての問題、および、システム運用上の負荷の問題となっています。問題が発生する条件は限られますが、少ない副作用で実現可能であるならば対処を行ってもよいように思います。

問題点の補足 2007/7/30 追記
md5 を計算する際に OS のディスクキャッシュが追い出され、環境によっては他のアプリケーションに影響を与えます(正式にはバッファキャッシュとかページキャッシュとか?)

目次

仕様についての評価

簡潔に言えば md5 sum の表示は必要か? ということになると思います。

評価の前提

コメント


修正案

修正案の評価

現行 ( md5 を常に計算 )

利点

欠点

md5 を計算しない

利点

欠点

コメント

md5 をキャッシュする (添付してある実装の場合)

利点

欠点

上記 2 者または 3 者を選択できるようにする

利点

欠点

コメント

修正案の実現

md5 の計算結果をキャッシュする

パッチ*2を以下に示します。

ファイル名が非常に長いなどでハッシュファイルを作成できない場合、毎回計算が実行されます。

Index: attach.inc.php
===================================================================
--- attach.inc.php     (revision 39)
+++ attach.inc.php     (revision 41)
@@ -47,6 +47,9 @@
 // mime-typeを記述したページ
 define('PLUGIN_ATTACH_CONFIG_PAGE_MIME', 'plugin/attach/mime-type');

+// use md5 cache mechanizm
+define('PLUGIN_ATTACH_HASH_CACHE', TRUE); // FALSE or TRUE
+
 //-------- convert
 function plugin_attach_convert()
 {
@@ -449,9 +452,67 @@
               $this->logname  = $this->basename . '.log';
               $this->exist    = file_exists($this->filename);
               $this->time     = $this->exist ? filemtime($this->filename) - LOCALZONE : 0;
-              $this->md5hash  = $this->exist ? md5_file($this->filename) : '';
+
+        $this->hashCacheFile =
+            CACHE_DIR . encode($page) . '_' . encode($this->file) .
+            ($age ? '.' . $age : '') . '.attach_hash';
+
+        if ( PLUGIN_ATTACH_HASH_CACHE ) {
+            $this->md5hash = $this->getHashCache();
+        } else {
+            $this->md5hash  = $this->exist ? md5_file($this->filename) : '';
+        }
       }

+    function getHashCache()
+    {
+          // cache file will be stored in cache/*.attach_md5 file.
+          // Format: 3 int and 1 string splited by \t
+          // cache version : int (0)
+          // size          : int (byte)
+          // stamp         : int (mtime)
+          // md5sum        : stringn (hex text)
+
+        if ( ! $this->exist ) { return ''; }
+
+        $cache_version = 0;
+
+          // open target file.
+        $fpf = fopen( $this->filename, "r" );
+        if( ! $fpf ) { return ''; } // It's strange...
+        $fresh  = fstat( $fpf ); // get stat info
+
+          // open hash cache file
+        $fpc = fopen( $this->hashCacheFile, "r" );
+        if( $fpc ) { // cache existing.
+            $cached = fscanf($fpc, "%d\t%d\t%d\t%s\n");
+            if ( $cached[0] == $cache_version  &&
+                 $cached[1] == $fresh['size']  &&
+                 $cached[2] == $fresh['mtime'] ) {  // fresh and fine cache. use it.
+                fclose( $fpc );
+                fclose( $fpf );
+                return $cached[3];
+                  // return "cache:" . $cached[3];
+            }
+            fclose( $fpc ); // close cache file once.
+        }
+
+        $md5 = md5_file($this->filename);
+
+          // Need to create cache
+        $fpc = fopen( $this->hashCacheFile, "w" );
+        if ( ! $fpc ) { fclose( $fpf ); return $md5; }
+
+          // generate cache file
+        fwrite($fpc,
+               sprintf("%d\t%d\t%d\t%s\n",
+                       $cache_version, $fresh['size'], $fresh['mtime'], $md5 ));
+        fclose( $fpc );
+        fclose( $fpf );
+        return $md5;
+          // return "gen:" . $md5;
+    }
+
       // ファイル情報取得
       function getstatus()
       {
@@ -617,7 +678,10 @@
                       }
               }

-              // バックアップ
+          // remove hash cache.
+        if ( PLUGIN_ATTACH_HASH_CACHE ) { @unlink($this->hashCacheFile); }
+
+          // バックアップ
               if ($this->age ||
                       (PLUGIN_ATTACH_DELETE_ADMIN_ONLY && PLUGIN_ATTACH_DELETE_ADMIN_NOBACKUP)) {
                       @unlink($this->filename);


コメント



*1 個人的には、PukiWiki がどのようなところでどのように利用されているか良くわからないので、md5 sum の必要性そのものに対する評価を行うよりは、現行の仕様を維持したまま負荷を出来るだけ軽減する方法を探したほうが良いと考えています。
*2 php は年に数回しかいじりません。添削歓迎します。

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-28 (木) 01:57:18
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.218 sec.

SourceForge