github.com/iron-io/functions@v0.0.0-20180820112432-d59d7d1c40b2/api/models/mq.go (about) 1 package models 2 3 import "context" 4 5 // Titan uses a Message Queue to impose a total ordering on jobs that it will 6 // execute in order. Tasks are added to the queue via the Push() interface. The 7 // MQ must support a reserve-delete 2 step dequeue to allow Titan to implement 8 // timeouts and retries. 9 // 10 // The Reserve() operation must return a job based on this total ordering 11 // (described below). At this point, the MQ backend must start a timeout on the 12 // job. If Delete() is not called on the Task within the timeout, the Task should 13 // be restored to the queue. 14 // 15 // Total ordering: The queue should maintain an ordering based on priority and 16 // logical time. Priorities are currently 0-2 and available in the Task's 17 // priority field. Tasks with higher priority always get pulled off the queue 18 // first. Within the same priority, jobs should be available in FIFO order. 19 20 // When a job is required to be restored to the queue, it should maintain it's 21 // approximate order in the queue. That is, for jobs [A, B, C], with A being 22 // the head of the queue: 23 // Reserve() leads to A being passed to a consumer, and timeout started. 24 // Next Reserve() leads to B being dequeued. This consumer finishes running the 25 // task, leading to Delete() being called. B is now permanently erased from the 26 // queue. 27 // A's timeout occurs before the job is finished. At this point the ordering 28 // should be [A, C] and not [C, A]. 29 type MessageQueue interface { 30 // Push a Task onto the queue. If any error is returned, the Task SHOULD not be 31 // queued. Note that this does not completely avoid double queueing, that is 32 // OK, Titan will perform a check against the datastore after a dequeue. 33 // 34 // If the job's Delay value is > 0, the job should NOT be enqueued. The job 35 // should only be available in the queue after at least Delay seconds have 36 // elapsed. No ordering is required among multiple jobs queued with similar 37 // delays. That is, if jobs {A, C} are queued at t seconds, both with Delay 38 // = 5 seconds, and the same priority, then they may be available on the 39 // queue as [C, A] or [A, C]. 40 Push(context.Context, *Task) (*Task, error) 41 42 // Remove a job from the front of the queue, reserve it for a timeout and 43 // return it. MQ implementations MUST NOT lose jobs in case of errors. That 44 // is, in case of reservation failure, it should be possible to retrieve the 45 // job on a future reservation. 46 Reserve(context.Context) (*Task, error) 47 48 // If a reservation is pending, consider it acknowledged and delete it. If 49 // the job does not have an outstanding reservation, error. If a job did not 50 // exist, succeed. 51 Delete(context.Context, *Task) error 52 } 53 54 type Enqueue func(context.Context, MessageQueue, *Task) (*Task, error)