Work that outlives the request that asked for it.
moontask is a task queue for MoonBit: a worker takes a message off a broker and runs it, a beat sends messages on a rhythm, and a chain, group or chord says what happens after. Brokers and result stores are separate modules, so a queue on one process downloads nothing it does not use.
publish, claim, settle. Open the figure on its own ↗
How to read it
Three objects, and everything the library does is one of them.
The tray · a queue
Cards wait in the order they were dealt. A message sits in a queue until a worker takes it; the front card is the one that goes first, and the leaf springs keep the pile at the lip so you can see how much is waiting.
The clock · a worker and a beat
The only thing that moves work. It takes the card, stamps the state on it and counts the punch. A beat is the same hand going round by itself: an interval, a cron line, or one instant.
The line · a chain, a group, a chord
Sealed cards hang in the order the desk finished them. A chain is one card carrying the next; a group is several hung together; a chord is the peg that waits until every card of its set is on the line.
A first run
An app owns the broker, the store and the counter. A task is a name, a policy and a body; sending one writes a message and hands back a handle that decodes the stored result back into the body's return type.
let broker = @moontask.MemoryBroker::new(clock=now)
let app = @moontask.App::new(broker, backend=broker, counter=broker, clock=now)
let greet = app.task("greet", fn(name : String, ctx : @moontask.Context) {
"hello \{name}, attempt \{ctx.attempt}"
})
let worker = app.worker(concurrency=4)
@async.with_task_group(async fn(group) {
group.spawn_bg(async fn() { worker.run() }, no_wait=true)
let handle = greet.send("ada")
println(handle.get(timeout=5000L))
worker.stop()
})
What it keeps track of
| Piece | What it is | Where it lives |
|---|---|---|
Broker | Publish, claim, confirm or reject | moontask/spec, implemented by MemoryBroker and moontask-redis |
Backend | Store and fetch the outcome of a run | moontask/spec |
Counter | Count the parts of a chord | moontask/spec |
Inspector | Report what a queue holds | moontask/spec, what a management page reads |
Worker | Take, run, settle, advance | moontask |
Beat, Schedule | Send on a rhythm | moontask |
Scheduler, Job | Run on a rhythm inside one process | moontask/schedule |
Where it runs
The queue, the beat and the canvas build for native, WebAssembly and JavaScript, with the timer as the only difference. The Redis module is what a queue across several processes runs on; it keeps each consumer's unconfirmed work in a list of its own and hands it back when the consumer's lease runs out.