-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.yaml
More file actions
434 lines (416 loc) · 14.7 KB
/
api.yaml
File metadata and controls
434 lines (416 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
openapi: 3.0.3
info:
title: Distributed Durable Timer Service API
description: |
A distributed, durable timer service that can schedule and execute HTTP webhook callbacks
at specified times with high reliability and scalability.
## Features
- Create one-time timers with custom payloads
- Durable persistence across service restarts
- At-least-once delivery semantics
- Configurable retry policies and timeouts
- Timer modification and cancellation
- Callback response can update timer schedule
- Namespace-based timer uniqueness
version: 1.0.0
contact:
name: Timer Service Team
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: http://localhost:8080/api/v1
description: Local development server
- url: https://timer-service.example.com/api/v1
description: Production server
paths:
/timers/create:
post:
summary: Create a new timer
description: |
Creates a new one-time timer that will execute an HTTP callback at the specified time.
Timer IDs are used for deduplication within the namespace.
Note that for most databases except Cassandra, calling this API with the same timer ID will overwrite the existing timer.
However, for Cassandra, calling this API with the same timer ID and same executeAt will overwrite the existing timer;
calling this API with the same timer ID and different executeAt will create a new timer. This is because Cassandra's upsert behavior
and the fact that the primary key is a combination of timer ID and executeAt -- which we do that for clustering and performance of batch reads and deletions.
If you want to update the timer with the same timer ID but different executeAt for Cassandra, you should use the update API.
operationId: createTimer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateTimerRequest'
examples:
simple_timer:
summary: Simple timer example
value:
namespace: "example-namespace"
id: "user-notification-123"
executeAt: "2024-12-20T15:30:00Z"
callbackUrl: "https://api.example.com/webhooks/timer"
payload:
userId: "user123"
action: "send_reminder"
message: "Don't forget about your meeting!"
complex_timer:
summary: Timer with custom retry policy
value:
namespace: "example-namespace"
id: "payment-retry-456"
executeAt: "2024-12-20T10:00:00Z"
callbackUrl: "https://payment.example.com/process"
payload:
orderId: "order-789"
amount: 99.99
currency: "USD"
retryPolicy:
maxRetries: 3
backoffMultiplier: 2.0
initialInterval: "30s"
callbackTimeoutSeconds: 10
responses:
'200':
description: Timer created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Timer'
'400':
$ref: '#/components/responses/BadRequest'
'500':
$ref: '#/components/responses/InternalServerError'
/timers/get:
post:
summary: Get timer status and detailed information
description: Query timer status and detailed information as specified in FR-1.5
operationId: getTimer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TimerSelection'
examples:
get_timer:
summary: Get timer example
value:
namespace: "example-namespace"
timerId: "user-notification-123"
responses:
'200':
description: Timer details
content:
application/json:
schema:
$ref: '#/components/schemas/Timer'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
/timers/update:
post:
summary: Update an existing timer
description: |
Update a timer's execution time, callback URL, or payload.
Only pending timers can be updated.
operationId: updateTimer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateTimerRequest'
examples:
update_time:
summary: Update execution time
value:
namespace: "example-namespace"
timerId: "user-notification-123"
executeAt: "2024-12-21T15:30:00Z"
update_payload:
summary: Update payload
value:
namespace: "example-namespace"
timerId: "user-notification-123"
payload:
userId: "user456"
action: "send_reminder"
message: "Updated reminder message"
responses:
'200':
description: Timer updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Timer'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
/timers/delete:
post:
summary: Delete a timer
description: |
Cancel and delete a timer. Only pending timers can be deleted.
Once deleted, the timer will not execute its callback.
operationId: deleteTimer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TimerSelection'
examples:
delete_timer:
summary: Delete timer example
value:
namespace: "example-namespace"
timerId: "user-notification-123"
responses:
'204':
description: Timer deleted successfully
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
components:
schemas:
TimerSelection:
type: object
required:
- namespace
- timerId
properties:
namespace:
type: string
description: Namespace identifier for the timer. It is for timer ID uniqueness. Also used for scalability design(tied to the number of shards). Must be one of the namespaces configured in the system.
example: "example-namespace"
timerId:
type: string
description: Unique identifier for the timer within the namespace
example: "user-notification-123"
CreateTimerRequest:
type: object
required:
- namespace
- id
- executeAt
- callbackUrl
properties:
namespace:
type: string
description: Namespace identifier for the timer. It is for timer ID uniqueness. Also used for scalability design(tied to the number of shards). Must be one of the namespaces configured in the system.
example: "example-namespace"
id:
type: string
description: Unique identifier for the timer within the namespace (used for deduplication)
example: "user-notification-123"
maxLength: 255
executeAt:
type: string
format: date-time
description: ISO 8601 timestamp when the timer should execute
example: "2024-12-20T15:30:00Z"
callbackUrl:
type: string
format: uri
description: HTTP URL to call when the timer executes, returning 200 with CallbackResponse means success, 4xx means invalid timer and no retry, otherwise will be retried.
example: "https://api.example.com/webhooks/timer"
maxLength: 2048
payload:
type: object
description: Custom JSON payload to include in the callback
example:
userId: "user123"
action: "send_reminder"
retryPolicy:
$ref: '#/components/schemas/RetryPolicy'
callbackTimeoutSeconds:
type: integer
description: Timeout for the HTTP callback in seconds
CallbackResponse:
type: object
required:
- ok
properties:
ok:
type: boolean
description: Whether the callback is successful. If false, the timer will be retried (same as not returning 200).
nextExecuteAt:
type: string
format: date-time
description: ISO 8601 timestamp when the timer should execute next time. Only valid when ok is false.
example: "2024-12-20T15:30:00Z"
UpdateTimerRequest:
type: object
required:
- namespace
- timerId
properties:
namespace:
type: string
description: Namespace identifier for the timer. It is for timer ID uniqueness. Also used for scalability design(tied to the number of shards). Must be one of the namespaces configured in the system.
example: "example-namespace"
timerId:
type: string
description: Unique identifier for the timer within the namespace
example: "user-notification-123"
executeAt:
type: string
format: date-time
description: New execution time for the timer
example: "2024-12-21T15:30:00Z"
callbackUrl:
type: string
format: uri
description: New callback URL, returning 200 with CallbackResponse means success, 4xx means invalid timer and no retry, otherwise will be retried.
example: "https://api.example.com/webhooks/timer-updated"
maxLength: 2048
payload:
type: object
description: New payload data
retryPolicy:
$ref: '#/components/schemas/RetryPolicy'
callbackTimeoutSeconds:
type: integer
description: New timeout for the HTTP callback in seconds
example: 15
Timer:
type: object
required:
- id
- namespace
- executeAt
- callbackUrl
- createdAt
- updatedAt
properties:
id:
type: string
description: Unique identifier for the timer within the namespace
example: "user-notification-123"
namespace:
type: string
description: Namespace identifier for the timer. It is used for scalability and timer ID uniqueness.
example: "example-namespace"
executeAt:
type: string
format: date-time
description: When the timer is scheduled to execute
example: "2024-12-20T15:30:00Z"
callbackUrl:
type: string
format: uri
description: HTTP URL to call when executing, returning 200 with CallbackResponse means success, 4xx means invalid timer and no retry, otherwise will be retried.
example: "https://api.example.com/webhooks/timer"
payload:
type: object
description: Custom payload data
example:
userId: "user123"
action: "send_reminder"
retryPolicy:
$ref: '#/components/schemas/RetryPolicy'
callbackTimeoutSeconds:
type: integer
description: Timeout for the HTTP callback in seconds
example: 30
createdAt:
type: string
format: date-time
description: When the timer was created
example: "2024-12-19T10:00:00Z"
updatedAt:
type: string
format: date-time
description: When the timer was last updated
example: "2024-12-19T10:00:00Z"
executedAt:
type: string
format: date-time
description: When the timer was executed (if applicable)
example: "2024-12-20T15:30:05Z"
RetryPolicy:
type: object
properties:
maxAttempts:
type: integer
description: Maximum number of attempts including retries
example: 3
maxAttemptsDuration:
type: string
description: the total duration of all attempts including retries
example: "1h"
initialInterval:
type: string
description: Initial retry interval (e.g., "30s", "1m")
example: "30s"
backoffMultiplier:
type: number
description: Multiplier for exponential backoff
example: 2.0
maxInterval:
type: string
description: Maximum retry interval
example: "5m"
Error:
type: object
required:
- error
- message
properties:
error:
type: string
description: Error code
example: "TIMER_NOT_FOUND"
message:
type: string
description: Human-readable error message
example: "Timer with ID 'user-notification-123' not found"
details:
type: object
description: Additional error details
timestamp:
type: string
format: date-time
description: When the error occurred
example: "2024-12-19T10:15:30Z"
responses:
BadRequest:
description: Bad request - invalid input parameters
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: "INVALID_INPUT"
message: "executeAt must be a future timestamp"
timestamp: "2024-12-19T10:15:30Z"
NotFound:
description: Timer not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: "TIMER_NOT_FOUND"
message: "Timer with ID 'user-notification-123' not found"
timestamp: "2024-12-19T10:15:30Z"
InternalServerError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: "INTERNAL_ERROR"
message: "An unexpected error occurred"
timestamp: "2024-12-19T10:15:30Z"