私は現在、小規模なWebサービスの設計に取り組んでおり、次の機能があります(簡略化)。
一部のユーザーアクションの後、待機期間(30秒から40時間の範囲)があり、それが経過すると、ユーザーが待機期間中にキャンセルしない限り、サーバーはタスクのデータベースエントリを更新する必要があります。実行されるタスクは非常に単純で、計算はわずかですが、遅延させる必要があります。
そして、私はこれを行う方法がわかりません...
同じような状況が一部のブラウザーベースのゲームで発生することを知っています。建物をアップグレードして、建物が完成した後にボーナスを獲得することはできますが、この機能がどのように実現されるかはわかりませんでした。それで、私の質問は、バックエンドのそのような問題に対処する「最先端の」方法、またはまったく何か方法があるのですか?
これにはいくつかの方法があります。最終的に何をするかは、サーバー側のスタック、サーバーに対する権限、および遅延イベントに必要な副作用の性質によって異なります。
私がそれらを見ると、あなたのオプションは:
event_fire_time <= now
およびevent_user = UserX
、およびそれらのイベントを「完了」します。すべてのシナリオで、イベントコードが処理しているレコードを必ずロックしてください(DBMSを使用している場合はトランザクションを使用)。
タスクを、たとえば以下の情報とともに、dbテーブルに保存する必要があります。
time_to_execute
:タスクが設定されたときのタイムスタンプ+秒単位の遅延to_do
:やるべきこと(これはバックエンドで理解できる必要があります)executed
:タスクがすでに実行されている場合は1、それ以外の場合は0(デフォルト)次に、スケジューラが必要です。cron
を使用できます。これにより、定期的に、たとえば毎分、バックエンドのエンドポイントにクエリが送信され、スケジュールされたタスクを含むdbテーブルにクエリが送信されます。このための疑似コードは次のようになります。
my_backend_endpoint_callback():
for task in tasks:
if not task.executed and time_to_execute > time.now():
result = execute_my_task(task.to_do)
if result == 0:
# task was properly executed
task.executed = 1
その後、トレースを保持するかどうかに応じて、実行されたすべてのタスクを削除する別のループを作成できます。
簡単な方法は、データベースに保留中のタスクテーブルを置くことです。
タスクを作成するには、アクション時間と、タスクの処理に必要なその他のデータを含む行をテーブルに追加します。テーブルに定期的にクエリを行い、期限が到来したタスクをアクションし、完了したタスクをテーブルから削除するバックグラウンドスレッドがあります。
これを「最先端」とは言いませんが、必要なことを行うための比較的単純で信頼性の高い方法です。
タスクが完了したら、ユーザーに通知する必要がありますか?すべてのクライアントがサーバーへのWebSocket接続を維持する必要があり、プッシュ通知を行うことができるため、状況は多少複雑になります。