scheduler_agent.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. require 'rufus-scheduler'
  2. module Agents
  3. class SchedulerAgent < Agent
  4. include AgentControllerConcern
  5. cannot_be_scheduled!
  6. cannot_receive_events!
  7. cannot_create_events!
  8. @@second_precision_enabled = ENV['ENABLE_SECOND_PRECISION_SCHEDULE'] == 'true'
  9. cattr_reader :second_precision_enabled
  10. description <<-MD
  11. This agent periodically takes an action on target Agents according to a user-defined schedule.
  12. # Action types
  13. Set `action` to one of the action types below:
  14. * `run`: Target Agents are run at intervals, except for those disabled.
  15. * `disable`: Target Agents are disabled (if not) at intervals.
  16. * `enable`: Target Agents are enabled (if not) at intervals.
  17. # Targets
  18. Select Agents that you want to run periodically by this SchedulerAgent.
  19. # Schedule
  20. Set `schedule` to a schedule specification in the [cron](http://en.wikipedia.org/wiki/Cron) format.
  21. For example:
  22. * `0 22 * * 1-5`: every day of the week at 22:00 (10pm)
  23. * `*/10 8-11 * * *`: every 10 minutes from 8:00 to and not including 12:00
  24. This variant has several extensions as explained below.
  25. ## Timezones
  26. You can optionally specify a timezone (default: `#{Time.zone.name}`) after the day-of-week field.
  27. * `0 22 * * 1-5 Europe/Paris`: every day of the week when it's 22:00 in Paris
  28. * `0 22 * * 1-5 Etc/GMT+2`: every day of the week when it's 22:00 in GMT+2
  29. ## Seconds
  30. You can optionally specify seconds before the minute field.
  31. * `*/30 * * * * *`: every 30 seconds
  32. #{"Only multiples of fifteen are allowed as values for the seconds field, i.e. `*/15`, `*/30`, `15,45` etc." unless second_precision_enabled}
  33. ## Last day of month
  34. `L` signifies "last day of month" in `day-of-month`.
  35. * `0 22 L * *`: every month on the last day at 22:00
  36. ## Weekday names
  37. You can use three letter names instead of numbers in the `weekdays` field.
  38. * `0 22 * * Sat,Sun`: every Saturday and Sunday, at 22:00
  39. ## Nth weekday of the month
  40. You can specify "nth weekday of the month" like this.
  41. * `0 22 * * Sun#1,Sun#2`: every first and second Sunday of the month, at 22:00
  42. * `0 22 * * Sun#L1`: every last Sunday of the month, at 22:00
  43. MD
  44. def default_options
  45. super.update({
  46. 'schedule' => '0 * * * *',
  47. })
  48. end
  49. def working?
  50. true
  51. end
  52. def check!
  53. control!
  54. end
  55. def validate_options
  56. if (spec = options['schedule']).present?
  57. begin
  58. cron = Rufus::Scheduler::CronLine.new(spec)
  59. unless second_precision_enabled || (cron.seconds - [0, 15, 30, 45, 60]).empty?
  60. errors.add(:base, "second precision schedule is not allowed in this service")
  61. end
  62. rescue ArgumentError
  63. errors.add(:base, "invalid schedule")
  64. end
  65. else
  66. errors.add(:base, "schedule is missing")
  67. end
  68. end
  69. before_save do
  70. self.memory.delete('scheduled_at') if self.options_changed?
  71. end
  72. end
  73. end