20
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
// THE SOFTWARE.
22
22
23
+ // (-- api-linter: core::0203::optional=disabled
24
+ // aip.dev/not-precedent: field_behavior annotation not available in our gogo fork --)
25
+ // (-- api-linter: core::0203::input-only=disabled
26
+ // aip.dev/not-precedent: field_behavior annotation not available in our gogo fork --)
27
+
23
28
syntax = "proto3" ;
24
29
25
30
package temporal.api.schedule.v1 ;
@@ -41,21 +46,23 @@ import "temporal/api/enums/v1/schedule.proto";
41
46
import "temporal/api/workflow/v1/message.proto" ;
42
47
43
48
// CalendarSpec describes an event specification relative to the calendar,
44
- // similar to a traditional cron specification. Each field can be one of:
49
+ // similar to a traditional cron specification, but with labeled fields. Each
50
+ // field can be one of:
45
51
// *: matches always
46
52
// x: matches when the field equals x
47
53
// x/y : matches when the field equals x+n*y where n is an integer
48
54
// x-z: matches when the field is between x and z inclusive
49
55
// w,x,y,...: matches when the field is one of the listed values
50
56
// Each x, y, z, ... is either a decimal integer, or a month or day of week name
51
57
// or abbreviation (in the appropriate fields).
52
- // A second in time matches if all fields match.
58
+ // A timestamp matches if all fields match.
59
+ // Note that fields have different default values, for convenience.
53
60
// Note that the special case that some cron implementations have for treating
54
61
// day_of_month and day_of_week as "or" instead of "and" when both are set is
55
62
// not implemented.
56
63
// day_of_week can accept 0 or 7 as Sunday
57
- // TODO: add relative-to-end-of-month
58
- // TODO: add nth day-of-week in month
64
+ // CalendarSpec gets compiled into StructuredCalendarSpec, which is what will be
65
+ // returned if you describe the schedule.
59
66
message CalendarSpec {
60
67
// Expression to match seconds. Default: 0
61
68
string second = 1 ;
@@ -73,6 +80,51 @@ message CalendarSpec {
73
80
string year = 6 ;
74
81
// Expression to match days of the week. Default: *
75
82
string day_of_week = 7 ;
83
+ // Free-form comment describing the intention of this spec.
84
+ string comment = 8 ;
85
+ }
86
+
87
+ // Range represents a set of integer values, used to match fields of a calendar
88
+ // time in StructuredCalendarSpec. If end < start, then end is interpreted as
89
+ // equal to start. This means you can use a Range with start set to a value, and
90
+ // end and step unset (defaulting to 0) to represent a single value.
91
+ message Range {
92
+ // Start of range (inclusive).
93
+ int32 start = 1 ;
94
+ // End of range (inclusive).
95
+ int32 end = 2 ;
96
+ // Step (optional, default 1).
97
+ int32 step = 3 ;
98
+ }
99
+
100
+ // StructuredCalendarSpec describes an event specification relative to the
101
+ // calendar, in a form that's easy to work with programmatically. Each field can
102
+ // be one or more ranges.
103
+ // A timestamp matches if at least one range of each field matches the
104
+ // corresponding fields of the timestamp, except for year: if year is missing,
105
+ // that means all years match. For all fields besides year, at least one Range
106
+ // must be present to match anything.
107
+ // TODO: add relative-to-end-of-month
108
+ // TODO: add nth day-of-week in month
109
+ message StructuredCalendarSpec {
110
+ // Match seconds (0-59)
111
+ repeated Range second = 1 ;
112
+ // Match minutes (0-59)
113
+ repeated Range minute = 2 ;
114
+ // Match hours (0-23)
115
+ repeated Range hour = 3 ;
116
+ // Match days of the month (1-31)
117
+ // (-- api-linter: core::0140::prepositions=disabled
118
+ // aip.dev/not-precedent: standard name of field --)
119
+ repeated Range day_of_month = 4 ;
120
+ // Match months (1-12)
121
+ repeated Range month = 5 ;
122
+ // Match years.
123
+ repeated Range year = 6 ;
124
+ // Match days of the week (0-6; 0 is Sunday).
125
+ repeated Range day_of_week = 7 ;
126
+ // Free-form comment describing the intention of this spec.
127
+ string comment = 8 ;
76
128
}
77
129
78
130
// IntervalSpec matches times that can be expressed as:
@@ -97,24 +149,56 @@ message IntervalSpec {
97
149
// definition of a time zone can change over time (most commonly, when daylight
98
150
// saving time policy changes for an area). To create a totally self-contained
99
151
// ScheduleSpec, use UTC or include timezone_data.
152
+ //
153
+ // For input, you can provide zero or more of: structured_calendar, calendar,
154
+ // cron_string, interval, and exclude_structured_calendar, and all of them will
155
+ // be used (the schedule will take action at the union of all of their times,
156
+ // minus the ones that match exclude_structured_calendar).
157
+ //
158
+ // On input, calendar and cron_string fields will be compiled into
159
+ // structured_calendar (and maybe interval and timezone_name), so if you
160
+ // Describe a schedule, you'll see only structured_calendar, interval, etc.
100
161
message ScheduleSpec {
162
+ // Calendar-based specifications of times.
163
+ repeated StructuredCalendarSpec structured_calendar = 7 ;
164
+ // cron_string holds a traditional cron specification as a string. It
165
+ // accepts 5, 6, or 7 fields, separated by spaces, and interprets them the
166
+ // same way as CalendarSpec.
167
+ // 5 fields: minute, hour, day_of_month, month, day_of_week
168
+ // 6 fields: minute, hour, day_of_month, month, day_of_week, year
169
+ // 7 fields: second, minute, hour, day_of_month, month, day_of_week, year
170
+ // If year is not given, it defaults to *. If second is not given, it
171
+ // defaults to 0.
172
+ // Shorthands @yearly, @monthly, @weekly, @daily, and @hourly are also
173
+ // accepted instead of the 5-7 time fields.
174
+ // Optionally, the string can be preceded by CRON_TZ=<timezone name> or
175
+ // TZ=<timezone name>, which will get copied to timezone_name. (There must
176
+ // not also be a timezone_name present.)
177
+ // Optionally "#" followed by a comment can appear at the end of the string.
178
+ // Note that the special case that some cron implementations have for
179
+ // treating day_of_month and day_of_week as "or" instead of "and" when both
180
+ // are set is not implemented.
181
+ // @every <interval>[/<phase>] is accepted and gets compiled into an
182
+ // IntervalSpec instead. <interval> and <phase> should be a decimal integer
183
+ // with a unit suffix s, m, h, or d.
184
+ repeated string cron_string = 8 ;
101
185
// Calendar-based specifications of times.
102
186
repeated CalendarSpec calendar = 1 ;
103
187
// Interval-based specifications of times.
104
188
repeated IntervalSpec interval = 2 ;
105
- // Any timestamps matching any of the exclude_calendar specs will be
106
- // skipped.
107
- repeated CalendarSpec exclude_calendar = 3 ;
108
- // Any timestamps before start_time will be skipped. Together, start_time
109
- // and end_time make an inclusive interval.
189
+ // Any timestamps matching any of exclude_* will be skipped.
190
+ repeated CalendarSpec exclude_calendar = 3 [ deprecated = true ]; // use exclude_structured_calendar
191
+ repeated StructuredCalendarSpec exclude_structured_calendar = 9 ;
192
+ // If start_time is set, any timestamps before start_time will be skipped.
193
+ // (Together, start_time and end_time make an inclusive interval.)
110
194
google.protobuf.Timestamp start_time = 4 [(gogoproto.stdtime ) = true ];
111
- // Any timestamps after end_time will be skipped.
195
+ // If end_time is set, any timestamps after end_time will be skipped.
112
196
google.protobuf.Timestamp end_time = 5 [(gogoproto.stdtime ) = true ];
113
197
// All timestamps will be incremented by a random value from 0 to this
114
- // amount of jitter. Default: 1 second
198
+ // amount of jitter. Default: 0
115
199
google.protobuf.Duration jitter = 6 [(gogoproto.stdduration ) = true ];
116
200
117
- // Time zone to interpret all CalendarSpecs in.
201
+ // Time zone to interpret all calendar-based specs in.
118
202
//
119
203
// If unset, defaults to UTC. We recommend using UTC for your application if
120
204
// at all possible, to avoid various surprising properties of time zones.
@@ -134,21 +218,17 @@ message ScheduleSpec {
134
218
// at 2:30am and specify a time zone that follows DST, that action will not
135
219
// be triggered on the day that has no 2:30am. Similarly, an action that
136
220
// fires at 1:30am will be triggered twice on the day that has two 1:30s.
221
+ //
222
+ // Also note that no actions are taken on leap-seconds (e.g. 23:59:60 UTC).
137
223
string timezone_name = 10 ;
138
224
bytes timezone_data = 11 ;
139
225
}
140
226
141
227
message SchedulePolicies {
142
228
// Policy for overlaps.
143
- // Note that this can be changed after a schedule has taken some actions, and we can't
144
- // provide 100% sensible semantics for all changes. The most confusing case would be
145
- // changes to/from ALLOW_ALL: with that policy multiple scheduled workflows can run
146
- // concurrently, but for all other policies only one can run at a time. Changing
147
- // between these two classes will leave all workflows with the other class alone.
148
- // E.g., if changing from ALLOW_ALL to CANCEL_OTHER, and there are workflows running,
149
- // those workflows will not be cancelled. If changing from ALLOW_ALL to SKIP with
150
- // workflows running, the running workflows will not cause the next action to be
151
- // skipped.
229
+ // Note that this can be changed after a schedule has taken some actions,
230
+ // and some changes might produce unintuitive results. In general, the later
231
+ // policy overrides the earlier policy.
152
232
temporal.api.enums.v1.ScheduleOverlapPolicy overlap_policy = 1 ;
153
233
154
234
// Policy for catchups:
@@ -195,10 +275,11 @@ message ScheduleState {
195
275
// If true, do not take any actions based on the schedule spec.
196
276
bool paused = 2 ;
197
277
198
- // If limited_actions is true, decrement remaining_actions after each action, and do
199
- // not take any more scheduled actions if remaining_actions is zero. Actions may still
200
- // be taken by explicit request. Skipped actions (due to overlap policy) do not count
201
- // against remaining actions.
278
+ // If limited_actions is true, decrement remaining_actions after each
279
+ // action, and do not take any more scheduled actions if remaining_actions
280
+ // is zero. Actions may still be taken by explicit request (i.e. trigger
281
+ // immediately or backfill). Skipped actions (due to overlap policy) do not
282
+ // count against remaining actions.
202
283
bool limited_actions = 3 ;
203
284
int64 remaining_actions = 4 ;
204
285
}
@@ -258,8 +339,7 @@ message ScheduleInfo {
258
339
google.protobuf.Timestamp create_time = 6 [(gogoproto.stdtime ) = true ];
259
340
google.protobuf.Timestamp update_time = 7 [(gogoproto.stdtime ) = true ];
260
341
261
- // Error for invalid schedule. If this is set, no actions will be taken.
262
- string invalid_schedule_error = 8 ;
342
+ string invalid_schedule_error = 8 [deprecated = true ];
263
343
}
264
344
265
345
message Schedule {
@@ -273,8 +353,7 @@ message Schedule {
273
353
// that's returned in ListSchedules.
274
354
message ScheduleListInfo {
275
355
// From spec:
276
- // Some fields are too large/unimportant for the purpose of listing, so we'll clear them
277
- // from this copy of spec: exclude_calendar, jitter, timezone_data.
356
+ // Some fields are dropped from this copy of spec: timezone_data
278
357
ScheduleSpec spec = 1 ;
279
358
280
359
// From action:
0 commit comments