電子メールモニターの同期
-
06-09-2019 - |
質問
特殊なコマンドメールに対して POP3 を使用して専用の Gmail アカウントを監視し、適切に反応する C# プログラムを作成しています。
信頼性を最大限に高めるために、このプログラムを全国の複数のコンピューターで実行します。現在、プログラムの 2 つのインスタンスが同じメッセージを読み取ることができ、そのうちの 1 つがメッセージを削除するという競合状態が発生しており、メッセージが 2 回処理されます。
各コマンドが正確に 1 回処理されるようにするにはどうすればよいですか?
Gmail の POP3 アクセスでは、各メッセージを 1 回だけ処理していました (RETR と DELE を 1 つのアトミック操作にしました) が、この動作を再現できなくなりました。
コンピューター間の通信の唯一の方法は、SQL Server と HTTP サーバー (私が制御します) です。
解決
私が考えてきた1つのオプションは、POP3のUIDLコマンドを使用して、すでに処理されたUIDLsの一意の列とSQL Serverでテーブルを持つことです。
次に、各メッセージをダウンロードする前に、デーモンは、それがエラーを得た場合、メッセージをスキップし、テーブルにUIDLを挿入して、でしょう。 (私は、SQL ServerのINSERTコマンドはアトミック操作であると仮定しています)。
他のヒント
まず最初に断っておきますが、POP3 がどのようなコマンドをサポートしているのかわかりません。明示的に「DELE」を実行して、メッセージが存在しない場合にエラーが発生する場合は、次のように言います。
- メッセージを RETR します
- メッセージを削除します
- DELE が成功した場合のみ処理
編集:
RFC1939 を読んだ後は、このアプローチが機能するはずです。RFC より:
DELE msg
Arguments:
a message-number (required) which may NOT refer to a
message marked as deleted
Restrictions:
may only be given in the TRANSACTION state
Discussion:
The POP3 server marks the message as deleted. Any future
reference to the message-number associated with the message
in a POP3 command generates an error. The POP3 server does
not actually delete the message until the POP3 session
enters the UPDATE state.
Possible Responses:
+OK message deleted
-ERR no such message
Examples:
C: DELE 1
S: +OK message 1 deleted
...
C: DELE 2
S: -ERR message 2 already deleted
もちろん、これは Gmail の実装が実際に RFC に準拠していることを前提としています。