123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- require 'fugit'
- module Agents
- class SchedulerAgent < Agent
- include AgentControllerConcern
- cannot_be_scheduled!
- cannot_receive_events!
- cannot_create_events!
- @@second_precision_enabled = ENV['ENABLE_SECOND_PRECISION_SCHEDULE'] == 'true'
- cattr_reader :second_precision_enabled
- description <<~MD
- The Scheduler Agent periodically takes an action on target Agents according to a user-defined schedule.
- # Action types
- Set `action` to one of the action types below:
- * `run`: Target Agents are run at intervals, except for those disabled.
- * `disable`: Target Agents are disabled (if not) at intervals.
- * `enable`: Target Agents are enabled (if not) at intervals.
- * If the option `drop_pending_events` is set to `true`, pending events will be cleared before the agent is enabled.
- # Targets
- Select Agents that you want to run periodically by this SchedulerAgent.
- # Schedule
- Set `schedule` to a schedule specification in the [cron](http://en.wikipedia.org/wiki/Cron) format.
- For example:
- * `0 22 * * 1-5`: every day of the week at 22:00 (10pm)
- * `*/10 8-11 * * *`: every 10 minutes from 8:00 to and not including 12:00
- This variant has several extensions as explained below.
- ## Timezones
- You can optionally specify a timezone (default: `#{Time.zone.name}`) after the day-of-week field using the labels in the [tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
- * `0 22 * * 1-5 Europe/Paris`: every day of the week when it's 22:00 in Paris
- * `0 22 * * 1-5 Etc/GMT+2`: every day of the week when it's 22:00 in GMT+2
- ## Seconds
- You can optionally specify seconds before the minute field.
- * `*/30 * * * * *`: every 30 seconds
- #{"Only multiples of fifteen are allowed as values for the seconds field, i.e. `*/15`, `*/30`, `15,45` etc." unless second_precision_enabled}
- ## Last day of month
- `L` signifies "last day of month" in `day-of-month`.
- * `0 22 L * *`: every month on the last day at 22:00
- ## Weekday names
- You can use three letter names instead of numbers in the `weekdays` field.
- * `0 22 * * Sat,Sun`: every Saturday and Sunday, at 22:00
- ## Nth weekday of the month
- You can specify "nth weekday of the month" like this.
- * `0 22 * * Sun#1,Sun#2`: every first and second Sunday of the month, at 22:00
- * `0 22 * * Sun#L1`: every last Sunday of the month, at 22:00
- MD
- def default_options
- super.update({
- 'schedule' => '0 * * * *',
- })
- end
- def working?
- true
- end
- def validate_options
- if (spec = options['schedule']).present?
- begin
- cron = Fugit::Cron.new(spec) or raise ArgumentError
- unless second_precision_enabled || (cron.seconds - [0, 15, 30, 45, 60]).empty?
- errors.add(:base, "second precision schedule is not allowed in this service")
- end
- rescue ArgumentError
- errors.add(:base, "invalid schedule")
- end
- else
- errors.add(:base, "schedule is missing")
- end
- end
- before_save do
- self.memory.delete('scheduled_at') if self.options_changed?
- end
- end
- end
|