No description
Find a file
2023-04-14 19:11:22 -06:00
.github/workflows Add redis support (#44) 2023-04-14 19:11:22 -06:00
backends Add redis support (#44) 2023-04-14 19:11:22 -06:00
config Add redis support (#44) 2023-04-14 19:11:22 -06:00
examples Add redis support (#44) 2023-04-14 19:11:22 -06:00
handler Add redis support (#44) 2023-04-14 19:11:22 -06:00
internal Make JobWithContext private 2023-03-21 09:54:08 -07:00
jobs Add redis support (#44) 2023-04-14 19:11:22 -06:00
logging Move backends to separate packages 2023-03-01 10:34:27 -07:00
testutils Move backends to separate packages 2023-03-01 10:34:27 -07:00
types Add redis support (#44) 2023-04-14 19:11:22 -06:00
.gitignore Add redis support (#44) 2023-04-14 19:11:22 -06:00
.go-version Bump golang version 2023-02-19 10:04:35 -05:00
.golangci.yaml Move backends to separate packages 2023-03-01 10:34:27 -07:00
.goreleaser.yaml Disable go mod tidy goreleaser hook 2023-03-07 10:52:50 -07:00
doc.go Add redis support (#44) 2023-04-14 19:11:22 -06:00
env.sample Add redis support (#44) 2023-04-14 19:11:22 -06:00
go.mod Add redis support (#44) 2023-04-14 19:11:22 -06:00
go.sum Add redis support (#44) 2023-04-14 19:11:22 -06:00
LICENSE.txt Add full AGPL license text 2023-02-14 15:00:39 -08:00
Makefile Acquire a new connection for every queue listener (#38) 2023-03-18 09:52:48 -07:00
neoq.go remove unused errors 2023-03-17 08:58:57 -07:00
neoq_test.go Add redis support (#44) 2023-04-14 19:11:22 -06:00
README.md Add redis support (#44) 2023-04-14 19:11:22 -06:00

Neoq

Background job processing for Go

Go Reference Gitter chat

Installation

go get github.com/acaloiaro/neoq

About

Neoq is a queue-agnostic background job framework for Go.

Neoq job handlers are the same, whether queues are in-memory for development/testing, or Postgres, Redis, or a custom queue for production -- allowing queue infrastructure to change without code change.

Developing/testing or don't need a durable queue? Use the in-memory queue.

Running an application in production? Use Postgres.

Have higher throughput demands in production? Use Redis.

Neoq does not aim to be the fastest background job processor. It aims to be fast, reliable, and demand a minimal infrastructure footprint.

What it does

  • Multiple Backends: In-memory, Postgres, Redis, or user-supplied custom backends.
  • Retries: Jobs may be retried a configurable number of times with exponential backoff and jitter to prevent thundering herds
  • Job uniqueness: jobs are fingerprinted based on their payload and status to prevent job duplication (multiple jobs with the same payload are not re-queued)
  • Job Timeouts: Queue handlers can be configured with per-job timeouts with millisecond accuracy
  • Periodic Jobs: Jobs can be scheduled periodically using standard cron syntax
  • Future Jobs: Jobs can be scheduled either for the future or immediate execution
  • Concurrency: Concurrency is configurable for every queue

Getting Started

Getting started is as simple as declaring queue handlers and adding jobs.

Additional documentation can be found in the wiki: https://github.com/acaloiaro/neoq/wiki

Error handling in this section is excluded for simplicity.

Add queue handlers

Queue handlers listen for Jobs on queues. Jobs may consist of any payload that is JSON-serializable.

Queue Handlers are simple Go functions that accept a Context parameter.

Example: Add a listener on the hello_world queue using the default in-memory backend

ctx := context.Background()
nq, _ := neoq.New(ctx)
nq.Start(ctx, "hello_world", handler.New(func(ctx context.Context) (err error) {
  j, _ := jobs.FromContext(ctx)
  log.Println("got job id:", j.ID, "messsage:", j.Payload["message"])
  return
}))

Enqueue jobs

Enqueuing jobs adds jobs to the specified queue to be processed asynchronously.

Example: Add a "Hello World" job to the hello_world queue using the default in-memory backend.

ctx := context.Background()
nq, _ := neoq.New(ctx)
nq.Enqueue(ctx, &jobs.Job{
  Queue: "hello_world",
  Payload: map[string]interface{}{
    "message": "hello world",
  },
})

Redis

Example: Process jobs on the "hello_world" queue and add a job to it using the redis backend

ctx := context.Background()
nq, _ := neoq.New(ctx,
  neoq.WithBackend(redis.Backend),
  redis.WithAddr("localhost:6379"),
  redis.WithPassword(""),
)

nq.Start(ctx, "hello_world", handler.New(func(ctx context.Context) (err error) {
  j, _ := jobs.FromContext(ctx)
  log.Println("got job id:", j.ID, "messsage:", j.Payload["message"])
  return
}))

nq.Enqueue(ctx, &jobs.Job{
  Queue: "hello_world",
  Payload: map[string]interface{}{
    "message": "hello world",
  },
})

Postgres

Example: Process jobs on the "hello_world" queue and add a job to it using the postgres backend

ctx := context.Background()
nq, _ := neoq.New(ctx,
  neoq.WithBackend(postgres.Backend),
  postgres.WithConnectionString("postgres://postgres:postgres@127.0.0.1:5432/neoq"),
)

nq.Start(ctx, "hello_world", handler.New(func(ctx context.Context) (err error) {
  j, _ := jobs.FromContext(ctx)
  log.Println("got job id:", j.ID, "messsage:", j.Payload["message"])
  return
}))

nq.Enqueue(ctx, &jobs.Job{
  Queue: "hello_world",
  Payload: map[string]interface{}{
    "message": "hello world",
  },
})

Example Code

Additional example integration code can be found at https://github.com/acaloiaro/neoq/tree/main/examples

Status

This project is currently in alpha. Future releases may change the API. It currently leaks some resources. It can handle unimportant workloads.