VMime Book 日本語訳 第6章 6-6

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>());