継続

継続インタフェースは Traffic Server の基本的なコールバックメカニズムです。 Continuations は不明瞭なデータ型 TSCont のインスタンスです。基本的な形式では、継続はハンドラー関数とミューテックスを表現します。

この章では下記のトピックをカバーします。

ミューテックスとデータ

下記のどれかを行う際、継続はミューテックスを伴って生成されなければなりません。

  • TSHttpHookAdd もしくは TSHttpSsnHookAdd で)大域的に HTTP フックに登録され、 TSContDataSet/Get を使用する。

  • TSHttpTxnHookAdd で)局所的に登録されるが、複数のトランザクションが TSContDataSet/Get を使用する。

  • TSCacheXXX, TSNetXXX, TSHostLookup, もしくは TSContSchedule API を使用する。

アクティベートされる前に、呼び出し元は継続のミューテックスを掴まなければなりません。この要求は継続のハンドラー関数がそのデータに安全にアクセスし、同時に複数の動作中の呼び出し元が発生するのを防ぐことができるようにするためです。(使用方法については サンプルプロトコルについて を見てください。)ミューテックスに守られるデータは TSContDataSet により継続に関連付けられる任意の大域、または継続のデータです。これは継続ハンドラー関数に作成されるローカルデータを含みません。関連付けられるデータ構造とミューテックスと共に生成される継続の典型的な例は、サンプルプロトコルプラグイン内で生成されるトランザクションステートマシンです。( トランザクションステートマシンを実装する方法の一つ を見てください)

再入可能な呼び出しは、継続を引数として渡した際に、 API の関数呼び出しとして同じスタックトレース内で API を呼び出し可能にします。例えば TSCacheRead (contp, mykey) を呼び出す場合、 contp のハンドラーは直接呼び出され、その後 TSCacheRead を返すことが可能です。

下記を含む問題を起こす可能性がある注意事項:

  • 継続はそれに関連付いたデータ( TSContDataGet )を持ちます。

  • 再入可能呼び出しは自身を継続として再入可能 API に渡します。この場合、継続は再入可能 API を呼び出した後にデータへのアクセスを試みるべきではありません。この理由は、 API によって送られるイベントを処理する継続のハンドラー内のコード部分によってデータが変更されているかもしれないからです。解放されたデータへのアクセスを避けるため、再入可能呼び出しの後は常に return することを推奨します。

下記は例とその説明です。

continuation_handler (TSCont contp, TSEvent event, void *edata) {
    switch (event) {
        case event1:
            TSReentrantCall (contp);
            /* Return right away after this call */
            break;
        case event2:
            TSContDestroy (contp);
            break;
    }
}

上の例は、まず継続が event1 を伴ってコールバックされる事を想定します。その後 event2 を受け取るために継続をスケジュールする再入可能呼び出しを行います。この呼び出しは再入可能なので、プロセッサーはすぐに event2 を伴って継続をコールバックし、継続は破棄されます。もし再入可能呼び出し後に継続かそのメンバーのどれかにアクセスを試みたら、解放されたデータへアクセスすることになる可能性があります。解放されたデータへのアクセスを避けるため、再入可能呼び出し後は継続やそのメンバーのいずれかへのアクセスをせず、単にハンドラーを抜けてください。

注意: ほとんどの HTTP トランザクションプラグインの継続は null でないミューテックスを必要としません。なぜならそれらは HTTP トランザクションの処理内で呼び出されるので、トランザクションのミューテックスを持っているためです。

継続のミューテックスを NULL として指定することも可能です。 TSHttpHookAdd の呼び出しによって継続をグローバルフックに登録する際にのみ、これを行うべきです。この場合では継続は異なるスレッドで動作する異なる HTTP SM のインスタンスにより同時に呼び出される可能性があります。全てのスレッドが同じミューテックスのロックを試みるため、ここでミューテックスを持つことは Traffic Server の性能を遅くし、かつ / または妨害する可能性があります。ミューテックスを持たないことの欠点は、継続がそれに関連付いたデータを持てなくなる(すなわち、 TSContDataGet/Set が使えなくなる)ことです。

NULL ミューテックスを使用する際、継続のデータにアクセスするのは危険ですが、通常は NULL ミューテックスを伴う継続はそもそも、それに関連付いたデータを持ちません。そのような継続の例は、 HTTP リクエストが読み込まれる度にコールバックされてリクエストのみで通過するべきか拒絶するべきか決定するものです。 HTTP トランザクションはその継続データを contp に与えます。