Skip to content
Build bf98f58

Scheduled Jobs

How scheduling works today

The app uses sidekiq-scheduler (gem sidekiq-scheduler ~> 6.0). The schedule is dynamic and DB-backed via the RecurringJob model:

  • Cron expressions live in the recurring_jobs table, scoped per store and per warehouse.
  • RecurringJob.refresh_schedule rebuilds Sidekiq's in-memory schedule from the DB.
  • sidekiq-unique-jobs prevents duplicate executions for jobs marked unique.

Operators add/edit scheduled jobs through the admin UI — no code/manifest change required.

Implications for k8s

The scheduler must be a singleton. If two pods both load the schedule, every job fires twice. The sidekiq-scheduler Deployment runs with replicas: 1 and SIDEKIQ_SCHEDULER_ENABLED=true. All other Sidekiq pods (default / limited / single-thread capsules) run with SIDEKIQ_SCHEDULER_ENABLED=false.

The k8s Deployment update strategy for the scheduler should be Recreate, not RollingUpdate. Briefly running zero schedulers during a rollout is fine; running two is not.

strategy:
  type: Recreate

sidekiq-unique-jobs provides a second line of defense (jobs declared unique won't double-enqueue), but we should not rely on it as the primary mechanism.

Don't migrate to k8s CronJobs (yet)

It would be tempting to convert each recurring job into a k8s CronJob. Don't. The schedule is dynamic and managed via the admin UI; moving to CronJobs would break that workflow and require a manifest change for every schedule edit.

Revisit if the singleton scheduler becomes a reliability problem.

Rake tasks (one-shot, manual)

Located in lib/tasks/:

  • lib/tasks/orders/demandware/import.rake — Demandware order import
  • lib/tasks/orders/shopify/import.rake — Shopify order import
  • lib/tasks/annotate_rb.rake, format_ruby_files.rake — dev-only

These are operator-run, not scheduled. To run them in k8s:

kubectl run oms-rake-$(date +%s) --rm -it --image=<image> --restart=Never -- \
  bundle exec rake orders:demandware:import

Or maintain a long-running "utility" pod (sleep infinity) that operators exec into. Decision for infra.

Recent ad-hoc rake task — server reboots

There's a recent rake task (commit 97c241653, POP-4372 / OS-2736) that reboots servers using the AWS CLI. This becomes irrelevant in k8s — "reboot" maps to kubectl rollout restart deployment/<name>. Plan to delete this rake task once the migration is complete.

Rails Event Store subscriptions

These aren't scheduled but they fire jobs reactively. No k8s implications — they run inside the existing Sidekiq workers:

  • Event::FulfillmentRequestAcceptedOrders::ConfirmFulfillmentJob
  • Event::FulfillmentRequestRejectedOrders::RevertFulfillmentJob
  • Event::PrintStationOrderCreatedPrintStation::CreateOrderJob
  • Event::PrintStationCancellationAcknowledgedOrders::PrintStation::CancellationAcknowledgedJob