VMime Book 日本語訳 第6章 6-6
2020-07-01 K.OHWADA
原文
VMime Book: A Developer’s Guide To VMime
https://www.vmime.org/public/documentation/book/vmime-book.pdf
第6章 メッセージングサービスの操作
Working with Messaging Services
6.6 タイムアウトの処理
Handling timeouts
メッセージングサービスが操作を実行し、サーバーからの応答を待機しているときに、予期しないエラーが発生する可能性があります(たとえば、サーバーが応答を停止したり、ネットワークリンクがダウンしたりします)。 すべての操作は同期であるため、戻る前に長時間「ブロック」される可能性があります(実際、サーバーからの応答を受信するか、基盤となるソケットシステムがエラーを返すまでループします)。 VMimeは、操作の期間を制御するメカニズムを提供します。 このメカニズムにより、プログラムは現在実行中の操作をキャンセルできます。 timeoutHandlerと呼ばれるインターフェースが提供されています
class timeoutHandler : public object { /∗∗ Called to test if the time limit has been reached. ∗ ∗ @return true if the timeout delay is elapsed ∗/ virtual const bool isTimeOut() = 0; /∗∗ Called to reset the timeout counter. ∗/ virtual void resetTimeOut() = 0; ∗ ∗/ virtual const bool handleTimeOut() = 0; };
操作の実行中、サービスは可変間隔でisTimeout()を呼び出します。 isTimeout()関数がtrueを返す場合、handleTimeout()が呼び出されます。 handleTimeout()関数がfalseを返す場合、操作はキャンセルされ、操作のタイムアウト例外がスローされます。 それ以外の場合、handleTimeout()がtrueを返すと、操作が続行され、タイムアウトカウンターがリセットされます。 関数resetTimeout()は、サーバーからデータを受信するたびに呼び出され、タイムアウト遅延をリセットします。 サービスを使用する場合、デフォルトのタイムアウトハンドラーが設定されます。 操作が30秒を超えてブロックされた場合(つまり、ネットワークリンクがダウンし、30秒以降データが受信されなかった場合)、操作のタイムアウト例外がスローされます。 次の例は、単純なタイムアウトハンドラーを実装する方法を示しています。
リスト6.12:単純なタイムアウトハンドラーの実装
Implementing a simple timeout handler
class myTimeoutHandler : public vmime::net::timeoutHandler { public : /∗∗ Called when the time limit has been reached (when ∗ isTimeOut() returned true). ∗ ∗ @return true to continue (and reset the timeout) or false to cancel the current operation myTimeoutHandler ( ) { } const bool isTimeOut() { return (time(NULL) >= m startTime + 30); m startTime = time(NULL); // 30 seconds timeout } void resetTimeOut() { m startTime = time(NULL); } const bool handleTimeOut() { std::cout << ”Operation timed out.” << std::endl; << ”Press [Y] to continue, or [N] to ” << ”cancel the operation . ” << std : : endl ; std::string response; std : : cin >> response ; return (response == ”y” || response == ”Y”); } private : time t m startTime; };
サービスにタイムアウトハンドラーを使用させるには、ファクトリクラスを記述して、サービスがハンドラークラスのインスタンスを作成できるようにする必要があります。 これは、サービスがサーバーへの複数の接続を同時に使用でき、各接続に独自のタイムアウトハンドラーが必要なために必要です。
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory { public : ref <timeoutHandler> create() { return vmime: : make shared <myTimeoutHandler>(); } };
次に、サービスオブジェクトでsetTimeoutHandlerFactory()メソッドを呼び出して、 セッション中に使用するタイムアウトハンドラファクトリ:
theService−>setTimeoutHandlerFactory(vmime: : make shared <myTimeoutHandlerFactory>());