web-dev-qa-db-ja.com

設計の質問:定期的なイベントシステムをどのように設計しますか?

定期的なイベントをサポートするイベントスケジューリングシステムの構築を任された場合、どのように行いますか?定期的なイベントが削除された場合、どのように処理しますか?将来のイベントがいつ発生するかをどのように確認できますか?

つまり、イベントを作成するときに、「毎日繰り返す」(または毎週、毎年など)を選択できます。

回答ごとに1つのデザインをお願いします。私はRuby/Railsに慣れていますが、デザインを表現したいものは何でも使用します。

面接で聞いたのですが、なかなかいい反応が出ませんでした。

注:だった すでにここで質問/回答済み しかし、以下に詳述するように、私はいくつかのより実用的な詳細を取得したいと思っていました:

  • 定期的なイベントの1つのインスタンスにコメントしたり、データを追加したりする必要がある場合、それはどのように機能しますか?
  • イベントの変更と削除はどのように機能しますか?
  • 将来のイベントがいつ発生するかをどのように計算しますか?
47
Joe Van Dyk

私はいくつかの時間的表現を Martin Fowlerによって概説された として実装することから始めました。これにより、スケジュールされたアイテムが実際にいつ発生するかがわかります。それはとてもエレガントなやり方です。私が最終的に得たのは、記事の内容を積み上げただけでした。

次の問題は、世界でどのように式を保存するかを理解することでした。もう1つの問題は、式を読み取るときに、それほど動的ではないユーザーインターフェイスにどのように適合するかということです。式をBLOBにシリアル化するだけの話がありましたが、式ツリーを歩いてその意味を理解するのは難しいでしょう。

解決策(私の場合)は、ユーザーインターフェイスがサポートする限られた数のケースに適合するパラメーターを格納し、そこからその情報を使用して時間式をオンザフライで生成することです(最適化のために作成するとシリアル化できます)。したがって、Scheduleクラスには、オフセット、開始日、終了日、曜日などのいくつかのパラメーターが含まれることになります。そこから、時間式を生成してハードワークを実行できます。

タスクのインスタンスを持つことに関しては、N日間のタスクを生成する「サービス」があります。これは既存のシステムへの統合であり、すべてのインスタンスが必要であるため、これは理にかなっています。ただし、このようなAPIを使用すると、すべてのインスタンスを保存しなくても、繰り返しを簡単に予測できます。

10
Greg Ogle

@ Joe Van Dykは尋ねました:「将来を見て、今後のイベントがいつになるか見ていただけませんか?」

参照/表示次のnイベントの発生を希望する場合は、次のいずれかを行う必要がありますa)事前に計算してどこかに保存するか、b)その場で計算して表示します。これは、どの夜のフレームワークでも同じです。

A)の欠点は、どこかに制限を設け、その後b)を使用する必要があることです。そもそもb)を使うだけで簡単です。

スケジューリングシステムはこの情報を必要とせず、nextイベントがいつであるかを知る必要があるだけです。

2
henriksen

プロジェクトのデータベースの終わりを管理していたとき、私は以前にこれをしなければなりませんでした。各イベントを個別のイベントとして保存するように要求しました。これにより、オカレンスを1つだけ削除することも、スパンを移動することもできます。 1つのオカレンスを変更して2つに変えるよりも、複数を削除する方がはるかに簡単です。次に、繰り返しの情報を含むrecurrenceIDを持つ別のテーブルを作成することができました。

2
Joe Phillips

私の頭のてっぺんから(タイピング/思考中にいくつかのことを修正した後):

必要な最小再発解像度を決定します。それがアプリの実行頻度です。多分それは毎日、多分5分ごとです。

定期的なイベントごとに、最新の実行時間、実行間隔、および必要に応じて有効期限などの他の機能を保存します。

アプリが実行されるたびに、すべてのイベントがチェックされ、(today/now + recurrenceResolution)と(recentRunTime + runInterval)が比較され、一致する場合はイベントが発生します。

0
clweeks

自分用のカレンダーアプリを書いたときmumble数年前、私は基本的にcronからスケジューリングメカニズムを盗み、それを定期的なイベントに使用しました。たとえば、1月を除く毎月第2土曜日に行われることには、「repeat = * 2-12 8-14 6」という命令が含まれます(毎年、2〜12か月、第2週は8日から14日まで実行されます。曜日に0ベースの番号付けを使用したため、土曜日は6)。

これにより、イベントが特定の日付に発生するかどうかを非常に簡単に判断できますが、「N日ごと」の再発を処理することはできず、UNIXに精通していないユーザーにとっては直感的ではありません。

個々のイベントインスタンスと削除/再スケジュールの一意のデータを処理するために、イベントが計算された距離を追跡し、結果のイベントをデータベースに保存しました。データベースでは、イベントに影響を与えることなく、イベントを変更、移動、または削除できました。元の再発イベント情報。新しい定期的なイベントが追加されると、すべてのインスタンスは、既存の「最後に計算された」日付まですぐに計算されました。

私はこれが最善の方法であるとは主張しませんが、それはaの方法であり、前述の制限内で非常にうまく機能する方法です。

0
Dave Sherohman

毎日、毎週、または週に数日などの単純な繰り返しイベントがある場合、スケジューラ/ cron/at機能でbuildtを使用することの何が問題になっていますか?実行可能/コンソールアプリを作成し、いつ実行するかを設定しますか?複雑なカレンダー、イベント、時間管理はありません。

:)

// W

0
Wiren

イベントを保存するときは、スケジュールをストアに保存します(「Schedules」と呼びます。次にイベントが発生するタイミングを計算し、それも保存します。たとえば、「 Events "。次に、" Events "を調べて、次のイベントがいつ発生するかを把握し、それまでスリープ状態にします。

アプリが「ウェイクアップ」すると、イベントが再び発生するタイミングが計算されます。これを「Events」に再度保存してから、イベントを実行します。

繰り返す。

スリープ中にイベントが作成されると、スリープが中断され、再計算されます。

アプリがスリープイベントなどから起動または回復している場合は、「Events」で合格したイベントを確認し、それに応じて行動します(見逃したイベントで何をしたいかによって異なります)。

このようなものは柔軟性があり、不要なCPUサイクルを必要としません。

0
henriksen