-
Notifications
You must be signed in to change notification settings - Fork 4
Getting Started
Let's start a project that uses the memory
backend.
Don't worry if you have no intention of using the memory
backend in production; we're using it here to keep this
introduction as simple as possible, by not requiring you to run any additional services. After all, that was a major
motivation for building neoq.
You can change backends at any time. The only code that changes when switching backends are the parameters passed to
neoq.New
. All other code remains the same. So while this Getting Started guide is written for the memory
backend,
few changes are necessary to switch to postgres
or redis
.
Begin by initializing a Go project and adding neoq
to it:
go mod init example.com/my_app
go get github.com/acaloiaro/neoq/backends/memory
If you'd like to use redis
or postgres
, simply go get
those backends instead of memory
. Refer to the
Backends article for more details on the backends available to you.
-
Import the neoq and stdlib packages used throughout this guide
main.go
:import ( "context" "log" "github.com/acaloiaro/neoq" "github.com/acaloiaro/neoq/backends/memory" "github.com/acaloiaro/neoq/handler" "github.com/acaloiaro/neoq/jobs" )
-
Initialize neoq with the memory backend
// We're using an `init()` function here to keep our queue listening code in `init()` separate from our enqueuing // code in `main()`, for the purposes of demonstration. Feel free to initialize neoq at any stage during your your // application's initialization; doing so in an init() function is not a requirement. func init() { ctx = context.Background() // neoq.New's second return value is an `error`, but we're avoiding error handling here for simplicity // `nq` is what we'll use to Enqueue new jobs and Start/Stop workers nq, _ = neoq.New(ctx, neoq.WithBackend(memory.Backend)) // create a handler that listens for new job on the "greetings" queue h := handler.New("greetings", func(ctx context.Context) (err error) { j, _ := jobs.FromContext(ctx) log.Printf("Hello, %s!", j.Payload["Name"]) done <- true return }) // Start starts listening for jobs on a queue with the given handler // If you have many jobs, which is usual, call Start() for every queue/Handler in your application nq.Start(ctx, h) }
-
Enqueue a job and wait for the job to complete. Since our Handler writes to
done
on completion, we can listen ondone
to wait for completion after the job has been enqueued.func main() { // be sure to shut down neoq before exiting to allow it to gracefully finish up any work in progress defer func() { nq.Shutdown(ctx) }() // Create a job to place on the queue. A job must specify a queue, but its payload may be empty j := &jobs.Job{Queue: "greetings", Payload: map[string]any{"Name": "World"}} // Enqueue the job for processing. Enqueue()'s first return value is the queued job's ID _, err := nq.Enqueue(context.Background(), j) if err != nil { log.Fatalf("Unable to enqueue job: %s", err) } // wait for the job to process before exiting <-done }
Upon completion, you will see the following greeting printed to the screen (with different timestamps, of course).
2023/09/15 17:49:23 Hello, World!
Congratulations! You've enqueued you first neoq job.
package main
import (
"context"
"log"
"github.com/acaloiaro/neoq"
"github.com/acaloiaro/neoq/backends/memory"
"github.com/acaloiaro/neoq/handler"
"github.com/acaloiaro/neoq/jobs"
)
var (
done = make(chan bool)
nq neoq.Neoq
ctx context.Context
)
// We're using an `init()` function here to keep our queue listening code in `init()` separate from our enqueuing
// code in `main()`, for the purposes of demonstration. Feel free to initialize neoq at any stage during your your
// application's initialization; doing so in an init() function is not a requirement.
func init() {
ctx = context.Background()
// neoq.New's second return value is an `error`, but we're avoiding error handling here for simplicity
// `nq` is what we'll use to Enqueue new jobs and Start/Stop workers
nq, _ = neoq.New(ctx, neoq.WithBackend(memory.Backend))
// create a handler that listens for new job on the "greetings" queue
h := handler.New("greetings", func(ctx context.Context) (err error) {
j, _ := jobs.FromContext(ctx)
log.Printf("Hello, %s!", j.Payload["Name"])
done <- true
return
})
// Start starts listening for jobs on a queue with the given handler
// If you have many jobs, which is usual, call Start() for every queue/Handler in your application
nq.Start(ctx, h)
}
func main() {
// be sure to shut down neoq before exiting to allow it to gracefully finish up any work in progress
defer func() { nq.Shutdown(ctx) }()
// Create a job to place on the queue. A job must specify a queue, but its payload may be empty
j := &jobs.Job{Queue: "greetings", Payload: map[string]any{"Name": "World"}}
// Enqueue the job for processing. Enqueue()'s first return value is the queued job's ID
_, err := nq.Enqueue(context.Background(), j)
if err != nil {
log.Fatalf("Unable to enqueue job: %s", err)
}
// wait until at least one job gets processed to exit
<-done
}
For API documenation and more usage examples, please refer to the neoq package documentation: https://pkg.go.dev/github.com/acaloiaro/neoq.