[mayaa-user:1023] Re: 頻繁にレンダリングを行っていると、ページのビルドが遅くなります

Susumu ISHIGAMI [E-MAIL ADDRESS DELETED]
2014年 4月 21日 (月) 18:02:53 JST


石上です。

以前sugaさんに下記のアドバイスを頂いた件について、実際に対応を行おうとしています。
もし、とても良い成果が得られれば、高負荷環境下でのMayaaの事例として、
可能な限りソースなどをフィードバック致します。

> - 更新を検出したらビルドを別スレッドで開始
> - ビルドが終わったのと同じ扱いで(タイムスタンプ更新)更新前のリソースで描画
> - 別スレッドでのビルドが終わったら差し替える

具体的には以下のように考えました。
ざっくりとした感じで申し訳ありませんが、下記1から3の対応方針に
おかしな点があればご指摘いただけますと幸いです。

1.isDeprecatedをOverride
  org.seasar.mayaa.impl.engine.specification.SpecificationImpl.isDeprecated()
  org.seasar.mayaa.impl.engine.TemplateImpl.isDeprecated()
  (もしかするとTemplateImplだけでも良いでしょうか。mayaaファイルの実行時更新は行いません)
  をOverrideしてTimestampで比較してtrueを返している条件の箇所を常にfalseを返すように変更すればよいかと思っています。

2.ファイル更新をフックしてEngineImpl.createSpecificationInstanceを呼び出す
  1.の時に更新を検知して裏でビルドを動かすような方式だと、
  > 更新後最初のアクセスでは必ず更新前で描画される
  となると思いますが、そうではなくファイルの更新をフックして、
  createSpecificationInstanceを呼び出せば比較的リアルタイムに引き継げるのではないかと思います。

  問題はこの中でもspec.isDeprecatedを何度も呼んでいるので、
  ビルド用の別スレッドでは、isDeprecatedがfalseを返さないように調整しなければならないと思っています。

3.ビルド用スレッドはSingleThreadExecutorでキューイングする
  createSpecificationInstance以下のメソッドがsynchronizedなしに実行されますが、
  本来このロジックはsynchronizedされて実行されることを想定されて作られていますので、
  並列実行を行うと、何か問題が起きるかもしれません。
  別オブジェクトでsynchronizedしても良いですが、スレッドがむやみに増えてしまわないように、
  シングルスレッドでキューイングしようと考えてます。

2014年3月16日 16:21 suga <ko.suga @ gmail.com>:
> suga です。
>
> 高負荷サイトでは再ビルドしない設定にすることを想定した造りのため、
> それに対応するにはTemplateBuilderやSpecificationBuilderに手を入れる
> (あるいは自作する)必要があるでしょう。
>
> アプローチとしてはこの方向が良いと思います。
>
>> ・レンダリング処理時は、ビルド処理と競合するリソースについては直接参照せず
>>  キャッシュを参照することにして、ビルドとレンダリングを干渉させないようにする
>
> - 更新を検出したらビルドを別スレッドで開始
> - ビルドが終わったのと同じ扱いで(タイムスタンプ更新)更新前のリソースで描画
> - 別スレッドでのビルドが終わったら差し替える
>
> 当然ですが更新後最初のアクセスでは必ず更新前で描画されるなど
> 不便な点があるでしょう。
>
> あとsynchronizedを外せるような造りにするとより良いでしょう。
>
> --
> suga ( ko.suga @ gmail.com )
>
>
> 2014-03-15 20:41 GMT+09:00 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>:
>> 石上です
>>
>> 連投で申し訳ありません。
>>
>> 一つのmayaaエンジンで、多数のWebページを提供しているWebサイトにて、
>> ローカル環境では数秒で終わっていたテンプレートのビルドに、数十秒
>> かかる現象を観測しています。
>>
>> おそらく、このような構成のサイトでは、ページが多い分、
>> 全体的にレンダリング処理が頻繁に行われていると思われます。
>> JMeterを使用して、ビルド済みのテンプレートをレンダリングする
>> 処理を頻繁に行うと、ローカル環境でも、当該テンプレートのビルド時間が
>> 遅くなることを確認いたしました。
>>
>> 私の推測では、Engineオブジェクトが事実上シングルトンとして実装されているため、
>> ビルド処理やレンダリング処理などあらゆる処理でEngineオブジェクトをsynchronizeしてしまっていて、
>> Engineオブジェクトのロック待ちが処理のボトルネックとなっているのではないかと思っています。
>>
>> この件について、もし何か対処法があればご教示いただけると有難いです。
>>
>> 私が思いついたアプローチとしては、
>>
>> ・レンダリング処理時は、ビルド処理と競合するリソースについては直接参照せず
>>  キャッシュを参照することにして、ビルドとレンダリングを干渉させないようにする
>>
>> ・ロックの範囲をテンプレートエンジン全体ではなく、フォルダ等一定のセグメントごとにロックする
>>
>> このとき、ランタイムで変更できるファイルを限定しても構いません
>> (例えばdefault.mayaaファイルの変更は検知しない)
>>
>> 曖昧で申し訳ありません。
>>
>> 更に情報が必要でしたら、提供致します。
>> 再現ソースが必要でしたら少し時間をいただければ作成致します。
>> _______________________________________________
>> mayaa-user mailing list
>> mayaa-user @ ml.seasar.org
>> https://ml.seasar.org/mailman/listinfo/mayaa-user
> _______________________________________________
> mayaa-user mailing list
> mayaa-user @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/mayaa-user



-- 
Susumu ISHIGAMI
susumu.ishigami @ gmail.com


mayaa-user メーリングリストの案内