Quick start
This program creates a worker, binds a queue to it and adds two jobs. Press Run to run it on the Go Playground. Press Edit to change it, then Run again (or Ctrl+Enter, Cmd+Enter on a Mac).
9 lines: package and imports
package main
import (
"fmt"
"time"
"github.com/goptics/varmq"
)
func main() {
worker := varmq.NewWorker(func(j varmq.Job[int]) {
fmt.Printf("Processing %d\n", j.Data())
time.Sleep(1 * time.Second)
}) // default concurrency is 1
defer worker.WaitUntilIdle()
queue := worker.BindQueue()
queue.Add(1)
queue.Add(2)
}
Tab inserts a tab. Esc leaves the editor. Ctrl+Enter runs.
Output
It prints Processing 1, then Processing 2 once the first job’s one-second sleep is over, then Program exited.
Line by line
worker := varmq.NewWorker(func(j varmq.Job[int]) {
fmt.Printf("Processing %d\n", j.Data())
time.Sleep(1 * time.Second)
}) // default concurrency is 1NewWorker builds a worker around a function that handles one job. The job type is generic: a Job[int] carries an int, which Data() returns. With no concurrency argument the worker runs one job at a time, which is why Processing 2 waits for the first job to finish.
defer worker.WaitUntilIdle()WaitUntilIdle blocks until the worker has no jobs left and is idle. Deferring it stops main from returning until both jobs are done. Without it, main would return right after the two Add calls and the program would exit before the jobs ran.
queue := worker.BindQueue()BindQueue creates a first-in, first-out queue and binds it to this worker. Jobs added to it go to this worker and no other.
queue.Add(1)
queue.Add(2)Add puts a job in the queue and returns immediately, without waiting for the job to run. It returns a handle to the job and true. It returns false if the queue did not take the job, for example because the queue is full or closed. This example ignores both. Jobs covers them.
Try it
Press Edit and pass a concurrency of 2 as the last argument to NewWorker:
}, 2)Run it again: both jobs now start together, so their two lines appear at the same moment, in either order. The timeline below shows both runs. Switch the concurrency and drag the time slider.
The quick-start program on a timeline of two seconds. Main calls Add twice at time zero, then waits in WaitUntilIdle. With concurrency 1 the worker runs job 1 from 0 to 1 second and job 2 from 1 to 2 seconds. With concurrency 2 both jobs run from 0 to 1 second. A slider moves through time, and the printed lines appear as time passes. Play replays the run.
worker := varmq.NewWorker(func(j varmq.Job[int]) {
fmt.Printf("Processing %d\n", j.Data())
time.Sleep(1 * time.Second)
}) // default concurrency is 1The Go Playground runs on a simulated clock, and so does this model: it draws the program, it does not time it. With concurrency 2 the two lines print together, in either order.
Next: workers and queues.