junohm410 / fjord-flea-market

A closed flea market app for FjordBootCamp members to easily buy and sell items within the community, featuring automated buyer selection and Discord notifications.
0 stars 0 forks source link

指定した締め切り期限に購入可能者を自動で抽選する機能の実装方法を調べる #18

Closed junohm410 closed 4 months ago

junohm410 commented 5 months ago

参考: https://odentakashi.github.io/2023/10/01/post6.html

ありえそうなアプローチ

cronとは https://e-words.jp/w/cron.html

junohm410 commented 5 months ago

cron vs ActiveJob

https://odentakashi.github.io/2023/10/01/post6.html

締め切りを過ぎた後の抽選をどのように行うか このサービスにおける重要な機能の一つに、抽選会の主催者が設定した締め切りを過ぎた後に抽選を行うというものがあります。 この処理は、締切日の翌日01:00時に定期的に実行されます。 この定期実行を実現するために、cronを使用して、Rakeタスクを実行しています。

最初は、この処理を実行するためにActiveJob+Redis+Sidekiqを検討していましたが、 アドバイスを受けて、このツールは非同期処理のためのものであり、特定の日時に実行することには向いていないと判断しました。 またUNIX系サーバーにおいてはcronを使用するのが一般的ということもアドバイスいただきました。

したがって、非同期処理から定期処理へのアプローチを採用し、締切後に抽選を行うためのRakeタスクを作成しました。 そして、このRakeタスクを毎日01:00に実行するようにcrontabを設定しました。

私のアプリの現在の仕様では、定期的(例: 毎日決まった時間)な実行ではなく、商品ごとに異なる締切に抽選を実行する(動的な処理時間の登録)。

cronは「定まった日時・頻度」に繰り返す処理を登録・実行するのに便利という理解 https://e-words.jp/w/cron.html

実行スケジュールは分刻みで指定することができ、毎時、毎日、毎週、毎月、再起動時(reboot)などを指定できるほか、該当する値を列挙したり範囲を指定することにより、「毎週月曜・水曜・金曜の午前0時」「9時から17時の毎時0分と30分」といった指定もできる。

cronは定期的に繰り返しコマンドを実行する場合に用いるもので、ある特定の日時に一度だけ実行したい場合はcronではなくatコマンドを使用する。

ActiveJobの場合はこんな感じで動的にジョブを登録できるかも

class Product < ApplicationRecord

  after_create :schedule_winner_selection

  # こんな感じで締め切り(deadline)時に実行される処理を登録
  def schedule_winner_selection
    SelectWinnerJob.set(wait_until: deadline).perform_later(id)
  end
end

そのほか

そもそも「何時何分に締め切り」みたいなことをする意味はそこまでないかも? (その厳密性は対して大事じゃない?) 6/12 締め切り -> 6/13 1時に抽選 は合理的かもしれない

junohm410 commented 5 months ago

📝 まずcronを使ったことがなかったので、簡単なrakeタスク(puts 'hello world')をcronで実行してログファイルに毎分吐き出すことを実験 -> 成功 簡単なrakeタスクをcronで定期実行する - shodan

デプロイに使う候補となる各PaaSには、cronを設定するための仕組みやWeb上の管理画面でのインターフェースなどが色々用意されている

junohm410 commented 4 months ago

cronで締め切り時に抽選を実行するアプローチ

という考え方ではなく、

という考え方になりそう。

この『その時点で締切が過ぎている商品を商品テーブルから検索し、もしあれば抽選処理を行う』をRakeタスクで書いておき、それをcronで定期実行する、というイメージ。

懸念

購入申込期限を「分単位」で設定できるようにしてしまうと、cronも分単位で設定し、(締め切りが過ぎた商品が本当にあるかどうかにかかわらず)毎分単位でRakeタスクを実行しないといけなくなる。

📝6/17 machidaさんと仕様について相談

締切は「日」レベルでOK。 (6/17が締切の場合、6/17 23:59:59まで希望を出せるイメージ)

抽選はその翌日の朝くらいに行い、出品者や当選者にDiscordでメッセージを送るような感じで仕様としてはOK。