June 28, 2005

究極のDiscussion Template? -6-

テーマ:Discussion Template

<話題の履歴>


究極のDiscussion Template? -5-

究極のDiscussion Template? -4-

究極のDiscussion Template? -3-

究極のDiscussion Template? -2-

究極のDiscussion Template? -1-



今回は@GetDocFieldを使った場合のPerformanceへの影響をDiscussion Templateを例に紹介します。



前回は、Discussion Tempalteを基にしたDBで親文書のSubjectを取得するために@GetDocFieldを使うようにしました。



しかし、Localでテストしてもこの影響を計ることはできません。


というのも、NRPCでの要求はServer/Client間で行われるものですし、Local DBの場合はNotes ClientのCache機能も働きません。


Performanceを計るためにはServerにDBを登録する必要があるのです。


皆さん、Test用のServerをお持ちでしょうか?


もしお持ちで無いならご自分のClientが稼動するPCにServerを入れてしまいましょう。


といっても、勿論ライセンスは必要です。



PCはIBM (Lenovo) ThinkPadのようなNote PCで十分ですが、ServerとClientを稼動させるために、Memoryは最低512MBは搭載しておくことをお勧めします。


私自身はこの記事を書くにあたり、ThinkPad X31 512MBのマシンを利用しています。



Localに導入してもあたかも別のServerに導入したのと同様に問題解析をすることは可能です。


MS Loopbackアダプターを利用すれば、Local環境でもServer/Clientの動作をそのまま体験できるのです。



Domino Serverが用意できたら作成したDBをServerにコピーして、稼動を確認してください。


文書はMain Topicとそれに対する返答文書の二つのみ登録しておきます。

 


DBを別の認証のIDで作成してしまった場合は、コピー後DBをTest Serverの環境の管理者IDまたはServer IDで署名しておいてください。



さて、準備はできました。


これから、NRPC Traceを利用した解析を行ってみましょう。



まず、Notes Clientを停止しNRPC Traceの設定を行います。


以前のNRPC Traceの記事 を参照し、以下のNotes.iniの設定を行います。


 Client_Clock=1
 Debug_Console=1
 Console_Log_Enabled=1

 

Notes.iniは最後に必ず改行が必要ですので、上記をCopy & Pasteされた場合は注意してください。


この設定により、


C:\[Notes Program Directory]\Data\IBM_TECHNICAL_SUPPORT


にNRPC Traceのデータが記録されるようになります。

 

 


また、Notes Clientを起動する前に、NotesのData DirectoryにあるCache.ndkを削除します。


稼動テストを行った段階で設計がLocal Cacheに保存されているため、そのDataを削除するためです。

 

 


設定が終わりましたので、Notes Clientを起動してみましょう。


Notes ClientのICONが二つでき、片方は以下のようなNotes Client Debug画面になっていることが確認できます。


Discuss_NRPC_1


ここではSequence 12まで来ていますので、これからの操作はこれ以降ということになるわけです。


環境によっては、Sequence Noはもう少し増える場合もあります。

 

 

また、NRPC Traceを当該DBだけを対象にしてとるためには、Replicator及びNew Mail到着の確認を停止しておくことをお勧めします。

 


これらのNRPCの要求が解析の邪魔になることがあるからです。

 

 


さて、それではServerに作成したDiscussion DBを開きます。


開いたら、最後のNRPCのSequence Noを記録しておきます。


更に返答文書を開きます。


この時点でもSequence Noを記録します。


ここまで行ったら、Notes ClientをMenuから終了します。

 

 


では、早速、C:\[Notes Program Directory]\Data\IBM_TECHNICAL_SUPPORTに保存されたconsole.logファイルをメモ帳で開いてみます。

 

 


最初に記録したSequence No以降のDBを開くところから見ていきましょう。


以下の①からがDBを開く所になります。②以降が返答文書を開くところとなります。③以降はNotes Clientを閉じる操作の後となっています。



(12-51 [12]) OPEN_DB(CN=DomSrv/O=LotusSW!!BlogTest\Discuss.nsf): (Connect to DomSrv/LotusSW: 20 ms) (Exch names: 0 ms)(Authenticate: 0 ms.)
(OPEN_SESSION: 0 ms)
0 ms. [134+290=424]
(13-51 [13]) ISDB2_RQST: 0 ms. [14+16=30]
(14-51 [14]) GET_UNREAD_NOTE_TABLE: 0 ms. [290+44=334]
(15-51 [15]) OPEN_NOTE(REP4925702C:002EEA37-NTFFFF0010,03000400): 0 ms. [48+1516=1564]
(16-51 [16]) OPEN_NOTE(REP4925702C:002EEA37-NT000002AE,08400000): 0 ms. [48+1770=1818]
(17-51 [17]) OPEN_NOTE(REP4925702C:002EEA37-NT0000029A,02400114): 20 ms. [48+1378=1426]
(18-51 [18]) OPEN_NOTE(REP4925702C:002EEA37-NT000002A6,0A400116): 30 ms. [48+1942=1990]
(19-51 [19]) OPEN_NOTE(REP4925702C:002EEA37-NT00000292,02400114): 0 ms. [48+3228=3276]
(20-51 [20]) OPEN_NOTE(REP4925702C:002EEA37-NT0000020E,02400114): 0 ms. [48+3504=3552]
(21-51 [21]) OPEN_NOTE(REP4925702C:002EEA37-NT000002BA,00400000): 0 ms. [48+28708=28756]
(22-51 [22]) OPEN_NOTE(REP4925702C:002EEA37-NT0000020A,00400000): 0 ms. [48+4070=4118]
(23-51 [23]) OPEN_NOTE(REP4925702C:002EEA37-NT0000029E,02400114): 0 ms. [48+2378=2426]
(24-51 [24]) OPEN_NOTE(REP4925702C:002EEA37-NT000002A2,0A400116): 0 ms. [48+1524=1572]
(25-51 [25]) OPEN_NOTE(REP4925702C:002EEA37-NT00000146,03400002): 0 ms. [48+9540=9588]
(26-51 [26]) OPEN_COLLECTION(REP4925702C:002EEA37-NT00000146,0040,4008): 10 ms. [130+9616=9746]
(27-51 [27]) GET_NOTE_INFO: 0 ms. [18+102=120]
(28-51 [28]) GET_COLLATION: 0 ms. [12+14=26]
(29-51 [29]) SET_COLLATION: 0 ms. [14+12=26]
(30-51 [30]) OPEN_NOTE(REP4925702C:002EEA37-NT000001FA,00400004): 0 ms. [48+16372=16420]
(31-51 [31]) SET_COLLATION: 0 ms. [14+12=26]
(32-51 [32]) READ_ENTRIES(REP4925702C:002EEA37-NT00000146): 0 ms. [80+410=490]
(33-51 [33]) OPEN_NOTE(REP4925702C:002EEA37-NT000002C2,00400000): 0 ms. [48+1616=1664]
(34-51 [34]) OPEN_NOTE(REP4925702C:002EEA37-NT000002BE,00400000): 0 ms. [48+1630=1678]

(35-91 [35]) OPEN_NOTE(REP4925702C:002EEA37-NT00000906,02400136): 0 ms. [48+1022=1070]
(36-91 [36]) OPEN_NOTE(REP4925702C:002EEA37-NT00000166,02400114): 0 ms. [48+23694=23742]
(37-91 [37]) OPEN_NOTE(REP4925702C:002EEA37-NT0000025E,03400014): 0 ms. [48+1566=1614]
(38-91 [38]) OPEN_NOTE(REP4925702C:002EEA37-NT00000212,03400014): 0 ms. [48+1608=1656]
(39-91 [39]) OPEN_NOTE(REP4925702C:002EEA37-NT00000216,03400014): 0 ms. [48+1546=1594]
(40-91 [40]) OPEN_NOTE(REP4925702C:002EEA37-NT0000017A,03400014): 0 ms. [48+1290=1338]
(41-91 [41]) OPEN_NOTE(REP4925702C:002EEA37-NT0000024A,03400014): 0 ms. [48+1520=1568]
(42-91 [42]) OPEN_NOTE(REP4925702C:002EEA37-NT000001F2,03400014): 0 ms. [48+1460=1508]
(43-91 [43]) OPEN_NOTE(REP4925702C:002EEA37-NT00000246,03400014): 0 ms. [48+1500=1548]
(44-91 [44]) OPEN_NOTE(REP4925702C:002EEA37-NT0000021A,03400014): 0 ms. [48+2232=2280]
(45-91 [45]) OPEN_NOTE(REP4925702C:002EEA37-NT00000206,03400014): 0 ms. [48+2856=2904]
(46-91 [46]) OPEN_NOTE(REP4925702C:002EEA37-NT000002D2,03400014): 10 ms. [48+1502=1550]
(47-91 [47]) OPEN_NOTE(REP4925702C:002EEA37-NT0000017E,03400014): 0 ms. [48+4098=4146]
(48-91 [48]) OPEN_NOTE(REP4925702C:002EEA37-NT00000162,02400014): 10 ms. [48+10740=10788]
(49-91 [49]) OPEN_NOTE(REP4925702C:002EEA37-NT00000242,02400014): 0 ms. [48+7892=7940]
(50-91 [50]) OPEN_NOTE(REP4925702C:002EEA37-NT000002B6,00400000): 0 ms. [48+6280=6328]
(51-91 [51]) GET_NOTE_INFO_BY_UNID: 0 ms. [52+66=118]
(52-91 [52]) OPEN_NOTE(REP4925702C:002EEA37-NT00000902,03400000): 0 ms. [48+916=964]
(53-91 [53]) DB_MODIFIED_TIME: 0 ms. [14+60=74]
(54-91 [54]) SET_TRUNC_INFO_RQST: 0 ms. [54+28=82]
(55-91 [55]) OPEN_NOTE(REP4925702C:002EEA37-NT000001CE,43400002): 0 ms. [48+830=878]
(56-91 [56]) SET_TRUNC_INFO_RQST: 0 ms. [34+28=62]
(57-91 [57]) OPEN_COLLECTION(REP4925702C:002EEA37-NT000001CE,0000,0000): 0 ms. [42+34=76]
(58-91 [58]) FIND_BY_KEY: 0 ms. [540+26=566] (Entry not found in index)

(59-118 [59]) CLOSE_COLLECTION(REP4925702C:002EEA37-NT00000146): 0 ms. [12+0=12]
(60-118 [60]) CLOSE_COLLECTION(REP4925702C:002EEA37-NT000001CE): 0 ms. [12+0=12]
(61-118 [61]) CLOSE_DB(REP4925702C:002EEA37): 0 ms. [14+0=14]
2005/06/27 15:51:59 Client shutdown complete


0 ms. [1625334354+49391616=1674725970] (Session Closed)



①では、以前Performance Tipsで紹介したように多段階設計が行われているために何度も設計要素が読み込まれているのが分かります。


実際にNotesPeek を使って設計要素を特定してみると分かるでしょう。



②でもResponse Formを開くために幾つかの設計要素を読み込んでいます。


②の中で、GET_NOTE_INFO_BY_UNIDに注目します。

 


これが、@GetDocFieldによってServerに要求されるNRPC Commandなのです。

 


その後、OPEN_NOTE(REP4925702C:002EEA37-NT00000902,03400000)により文書を開いていることが分かります。

 


では、NotesPeekでこのDiscussion DBのMain TopicのNoteIDを見てみましょう。

 


Note-IDは確かに"0x902"となっていて、この文書を読み込んでいることが分かるわけです。

 


では、Discussion DBのMain Topicの文書のPropertyで文書のSizeを確認します。

 


簡単な文書であれば、400 Bytes程度ですが、NRPC Trace上のDownload Bytesは916 Bytesとなっています。

 


もし、Main TopicのBody Fieldに大きなImageとかが貼り付けてられていた場合どうなるでしょうか?

 


勿論、そのDataが全てNetwork上を流れることになるのです。

 


実際に大きなBitmapでも貼り付けてNRPC Traceを取得すると事実が確認できます。

 


例えばMain TopicのSizeを5K Bytesくらいにして測定すると、

 

 


(51-45 [51]) GET_NOTE_INFO_BY_UNID: 0 ms. [52+66=118]
(52-45 [52]) OPEN_NOTE(REP4925702C:002EEA37-NT00000902,03400000): 0 ms.
[48+56828=56876]

 

 

のようになり、受信バイトが増加していることが明確に分かります。


いかがでしょう?


このように、@GetDocFieldを使うと簡単に機能が実装できるからといって、それを使ってしまうとPerformanceを著しく低下させるApplicationの作り方をしてしまっていることになるのです。

 


では、次回はこの方法ではなく、@DBLookupを使って同様の実装を行ってみることにしましょう。


<続く>


いいね!した人  |  コメント(0)  |  リブログ(0)
最近の画像つき記事
 もっと見る >>
June 27, 2005

究極のDiscussion Template? -5-

テーマ:Discussion Template

<話題の履歴>


究極のDiscussion Template? -4-

究極のDiscussion Template? -3-

究極のDiscussion Template? -2-

究極のDiscussion Template? -1-



今回は親文書や主文書の情報を作成時に保持するのではなく、リアルタイムに取得して表示するための改造を始めてみることにしましょう。

 

 

 
対象となるFieldは前回設計を調べた通り、"OriginalSubject"、"ImmediateParentSubject"、"ParentSubject"となります。

 

 


では、まず、"OriginalSubject"を取得することを考えて見ましょう。

 
これはMain TopicのSubjectを保持しているFieldです。


Fieldの設定は「作成時の計算結果」になっていますが、これを変更して「表示用の計算結果」に変更します。

 
これにより、文書に主文書のSubjectは保持しなくなります。

 

 

式は以下のような式が設定されていますが、この式も削除します。

 

 

@If(@IsAvailable(OriginalSubject); OriginalSubject; Subject)

 

 

 
さて、新しい式を考えて見ましょう。

 

 

主文書のSubjectを取る必要があるわけですが、何を使って取得すればよいでしょうか?

 

賢明な皆さんは直ぐに気が付かれるでしょうが、ここでMainIDを利用するのです。

 

MainID Fieldは「作成時の計算結果」で文書が作成された時に親文書が持っているMainID Fieldの値を引き継いでいくようになっています。

 

 

では、このMainIDでどのようにしたら、主文書のSubjectが取得できるでしょうか?

 

 

MainIDは主文書のDocument UNIDですから、@GetDocField( DocumentUNID ; FieldName )を使うことができます。

 

 

あるいは、Document UNIDでSortしたViewを作成して@DBLookupで参照するという方法もあるでしょう。

 

 

 

 

以前、Performance Design Tips で@GetDocFieldを使うとPerformanceが悪くなるということを紹介しました。

 

 

ここでは、@GetDocFieldを利用して、Performanceが悪くなることを実証してみることにします。



先程はOriginalSubject Fieldを改造することから手を付け始めましたが、一旦この作業は中止することにします。


というのもOriginalSubject Fieldは隠しFieldとなっていて文書に表示するために別の所にFieldを移動するか表示用のFieldを別途設ける必要がありますので、実験のためには作業が多すぎるからです。


今回は、ParentSubject Fieldを対象にして行います。


ParentSubject Fieldはその名の通り親文書のSubjectを持ったFieldで、"Response"や"Response to Response" Formに含まれる"RespBanner" Subformの中に定義されています。


このFieldもOriginalSubject Fieldと同様に作成時の計算結果になっています。



確認のために改造を行う前に、Main Topicを作成してからResponseを作成し、その後最初に作成したMain Topicを修正して返答文書を開いてみましょう。


Main TopicのSubjectが変更されても返答文書に表示される"Response to:"のSubjectは古いままのSubjectが表示されていることが分かります。



では、早速このFieldを変更して常に最新の親文書のSubjectが表示できるようにしましょう。



まず、Fieldのタイプを「作成時の計算結果」から「表示用の計算結果」に変更します。


これにより、親文書のSubjectは保持されなくなります。


また、書かれている式も削除し、元の式の代わりに以下の式を設定します。



@If(@IsNewDoc; Subject ;@GetDocField(@Text($Ref);"Subject"))



皆さんご存知のように親文書へのLinkは$RefというSystem Fieldに保持しています。


これを使って@GetDocFieldで親文書のSubjectの取得が可能です。


また、@IsNewDocで判断させているのには理由があります。


$Ref Fieldは新規文書を作成した場合、保持されていないFieldであり、文書が保存されて初めて保持されます。


つまり、新規文書作成時には$Refは値が無いため、@GetDocFieldがErrorしてしまうからです。


ParentSubjectの左側に作成されているDocLinkParent Fieldを参照してみてください。


同様に@IsNewDocで判断して処理していることがお分かり頂けるでしょう。



設計変更を保存し、文書を作成して試してみましょう。


親文書のSubjectを変更しても子文書に表示される親文書のSubjectは常に最新の物が表示されるようになったことが確認できます。



今回はLocalにDiscussion DBを作成して試していますし、単純な文書で動作確認されていますのでPerformanceに関しては全く分からないのではないでしょうか?



ここに開発者の落とし穴があるのです。


開発する際は、Localで開発したりTest環境を使って開発することがほとんどで、まさか本番環境で直接設計を変更するようなことは皆さん行われていないと思います。


このような環境では@GetDocFieldがどのように動いていてPerformanceにどのように影響するかは気がつかないのです。


では、次回はこの設計変更がPerformanceにどのような影響を及ぼすのかを以前紹介したNTPC Trace を用いて解析してみることにしましょう。


<続く>


いいね!した人  |  コメント(0)  |  リブログ(0)
June 23, 2005

究極のDiscussion Template? -4-

テーマ:Discussion Template

<話題の履歴>


究極のDiscussion Template? -3-

究極のDiscussion Template? -2-

究極のDiscussion Template? -1-



前回は、執筆者へのMail機能を付け加えてみました。


Notes 7のDiscussion Templateでは、そのようなことをしなくてもSametimeさえ導入されていればSametimeのAwareness(在席確認)がDiscussion Templateでも標準装備されていますので、直接Chatで会話するという手もあります。


また、このChatでの会話には会話時刻を打刻したり、Mail DBやFileに保存する機能も備わっていますので、Mail機能は必要ないかも知れませんが、Sametimeだけでは相手が在席していない限り会話できないですし、Sametimeが導入されていない場合もあるでしょうから、そのような場合に活用頂けると言う事で許してください。



今回は、ちょっと趣向を変えてDiscussion Templateについて少し考えてみることにしましょう。



まず、Discussion DBの"Main Topic"や"Response"、"Response to Response" Formを開いて見てみます。

 

そこには、MainIDというFieldが見つかるでしょう。


このFieldは常に、Main Topic(主文書)の文書のUNIDを保持するようにできています。


このFieldはR4.xの頃には無かったFieldで、確かNotes/Domino 6以降から設定されているのではないでしょうか?

 

これは使い道があるからこそ追加されているわけです。

 

実際R4.xの頃になくて、私はR4.xでDiscussion Templateを拡張するために、このFieldを追加しました。

 

 

 

その辺の改造は次回以降の話題にするとして、もう少しDiscussion Templateの中身を見ていきましょう。


"Response"や"Response to Response"のFormをDesignerで開いてみましょう。

 

表が作成されていて、2番目の表部分はSubformで構成されています。

 

その部分をダブルクリックすると、"Shared Response Header"というSubformが開かれます。

 

その中にある、Fieldを見てみることにしましょう。

 


まず、"OriginalSubject"というFieldが見つかるでしょう。

 

このFieldは作成時の計算結果Fieldとして定義されており、以下の式が設定されています。


@If(@IsAvailable(OriginalSubject); OriginalSubject; Subject)


つまり、返答文書(Response)を作成した場合は"Main Topic"にはこのFieldはありませんから、Main TopicのSubjectが設定されますし、返答への返答文書(Response to Response)を作成した場合は、返答文書にある"OriginalSubject"が設定されます。

 

つまり、このFieldは常にMain TopicのSubjectを返答文書に引き継いで保持し続けていくのです。


では、Main TopicのSubjectが途中で変更されてしまったらどうなるでしょう?

 

当然このFieldは自動更新されるわけではありません。

 

つまり、古い状態のMain TopicのSubjectを持ち続けるわけです。

 

DBを全文検索した場合もこのFieldの値が検索条件にヒットしてしまい、適切な検索が出来ないといったことが生じるかも知れません。

 

かといって、このFieldを直そうとすると、Agentで直してやるなどが必要ですし、文書を編集してしまうと、一般の利用者に未読文書となってしまい、未読を管理して新着記事を検索しているような人もいますので、このような処理はできないでしょう。

 


また、"ImmediateParentSubject"、"ParentSubject"というFieldがありますが、これらも作成時の計算結果Fieldですので上記と同じことが言えるわけです。

 

 

 

さて、次回からは親文書が編集された場合でもこれらのFieldをいつも正しい値にすることを考えていきましょう。

 

 

<続く>


いいね!した人  |  コメント(0)  |  リブログ(0)

AD

Ameba人気のブログ

Amebaトピックス

      ランキング

      • 総合
      • 新登場
      • 急上昇
      • トレンド

      ブログをはじめる

      たくさんの芸能人・有名人が
      書いているAmebaブログを
      無料で簡単にはじめることができます。

      公式トップブロガーへ応募

      多くの方にご紹介したいブログを
      執筆する方を「公式トップブロガー」
      として認定しております。

      芸能人・有名人ブログを開設

      Amebaブログでは、芸能人・有名人ブログを
      ご希望される著名人の方/事務所様を
      随時募集しております。