### Quick Start with PostgreSQL (pgx v5) Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initialize the pgx v5 driver, register a worker, create a client, enqueue a job, and start a worker pool. Ensure DATABASE_URL is set in the environment. ```go import ( "github.com/kirimatt/goncordia" "github.com/kirimatt/goncordia/core" pgxdriver "github.com/kirimatt/goncordia/driver/pgxv5" "github.com/jackc/pgx/v5/pgxpool" ) pool, _ := pgxpool.New(ctx, os.Getenv("DATABASE_URL")) d := pgxdriver.New(pool) d.Migrate(ctx) type SendEmailArgs struct { To string `json:"to"` Subject string `json:"subject"` } func (SendEmailArgs) Kind() string { return "send_email" } registry := core.NewRegistry() core.RegisterWorker(registry, core.WorkerFunc[SendEmailArgs]( func(ctx context.Context, job *core.Job[SendEmailArgs]) error { return sendEmail(job.Args.To, job.Args.Subject) }, ), core.WorkerOpts{MaxRetry: 5}) client := pgxdriver.NewClient(d, goncordia.ClientConfig{}) client.Enqueue(ctx, SendEmailArgs{To: "user@example.com", Subject: "Welcome"}, nil) wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default"}, Concurrency: 10, }) wp.Start(ctx) // blocks; call wp.Stop() to drain gracefully ``` -------------------------------- ### Install Cassandra/ScyllaDB Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the Cassandra/ScyllaDB adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/cassandra github.com/gocql/gocql ``` -------------------------------- ### Install Redis Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the Redis adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/redis github.com/redis/go-redis/v9 ``` -------------------------------- ### Install Goncordia Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the main Goncordia package using go get. ```bash go get github.com/kirimatt/goncordia ``` -------------------------------- ### Install GORM Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the GORM adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/gorm gorm.io/gorm ``` -------------------------------- ### Install Bun Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the Bun adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/bun github.com/uptrace/bun ``` -------------------------------- ### Quick Start with MongoDB Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initialize the MongoDB driver, connect to the client, and set up a Goncordia client. Demonstrates transactional inserts using `UseSession` and `StartTransaction`. ```go import ( mongodriver "github.com/kirimatt/goncordia/driver/mongodb" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) client, _ := mongo.Connect(ctx, options.Client().ApplyURI(os.Getenv("MONGO_URI"))) d, err := mongodriver.New(ctx, client, "myapp") // fails if not a replica set d.Migrate(ctx) mqClient := mongodriver.NewClient(d, goncordia.ClientConfig{}) // Transactional insert via mongo.SessionContext mongoClient.UseSession(ctx, func(sc mongo.SessionContext) error { sc.StartTransaction() db.Collection("orders").InsertOne(sc, order) mqClient.EnqueueTx(sc, sc, SendConfirmationArgs{OrderID: order.ID}, nil) return sc.CommitTransaction(sc) }) ``` -------------------------------- ### Install OpenTelemetry integration Source: https://github.com/kirimatt/goncordia/blob/main/README.md Use 'go get' to install the OpenTelemetry integration package for Goncordia. ```bash go get github.com/kirimatt/goncordia/otel ``` -------------------------------- ### MongoDB Setup (Replica Set Required) Source: https://context7.com/kirimatt/goncordia/llms.txt Initializes a MongoDB driver, requiring a replica set. Connects to MongoDB and creates a driver instance, returning an error if the setup is not a replica set. ```go // --- MongoDB (replica set required) --- import mongodriver "github.com/kirimatt/goncordia/driver/mongodb" mc, _ := mongo.Connect(ctx, options.Client().ApplyURI(os.Getenv("MONGO_URI"))) d, err := mongodriver.New(ctx, mc, "myapp") // error if not a replica set d.Migrate(ctx) ``` -------------------------------- ### Install MongoDB Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the MongoDB adapter for Goncordia. A replica set is required. ```bash go get github.com/kirimatt/goncordia/driver/mongodb go.mongodb.org/mongo-driver/mongo ``` -------------------------------- ### PostgreSQL/MySQL/SQLite Setup with database/sql Source: https://context7.com/kirimatt/goncordia/llms.txt Sets up a driver using the standard database/sql package for PostgreSQL, MySQL, or SQLite. Requires opening a database connection and specifying the driver type. ```go // --- PostgreSQL / MySQL / SQLite via database/sql --- import stdlibdriver "github.com/kirimatt/goncordia/driver/stdlib" db, _ := sql.Open("pgx", os.Getenv("DATABASE_URL")) d := stdlibdriver.New(db, stdlibdriver.Postgres) // or stdlibdriver.MySQL / stdlibdriver.SQLite d.Migrate(ctx) ``` -------------------------------- ### Install Cloud Firestore Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the Cloud Firestore adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/firestore cloud.google.com/go/firestore ``` -------------------------------- ### Install ClickHouse Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the ClickHouse adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/clickhouse github.com/ClickHouse/clickhouse-go/v2 ``` -------------------------------- ### Bun Adapter Setup and Transactional Enqueue Source: https://context7.com/kirimatt/goncordia/llms.txt Integrates Goncordia with Bun.SQL. Initializes the driver with a *bun.DB instance and demonstrates enqueuing a job within a Bun transaction. ```go // --- bun adapter --- import bundriver "github.com/kirimatt/goncordia/driver/bun" d := bundriver.New(db) // db is *bun.DB d.Migrate(ctx) tx, _ := db.BeginTx(ctx, nil) tx.NewInsert().Model(&order).Exec(ctx) client.EnqueueTx(ctx, tx, SendEmailArgs{OrderID: order.ID}, nil) tx.Commit() ``` -------------------------------- ### Install gontest for testing Source: https://github.com/kirimatt/goncordia/blob/main/README.md Use 'go get' to install the gontest package for testing Goncordia workers. ```bash go get github.com/kirimatt/goncordia/gontest ``` -------------------------------- ### Quick Start with Bun Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initialize the Bun driver and Goncordia client. Demonstrates transactional inserts where a job is enqueued atomically with a Bun record. ```go import ( bundriver "github.com/kirimatt/goncordia/driver/bun" "github.com/uptrace/bun" ) d := bundriver.New(db) // db is *bun.DB d.Migrate(ctx) client := bundriver.NewClient(d, goncordia.ClientConfig{}) tx, _ := db.BeginTx(ctx, nil) tx.NewInsert().Model(&order).Exec(ctx) client.EnqueueTx(ctx, tx, SendConfirmationArgs{OrderID: order.ID}, nil) tx.Commit() ``` -------------------------------- ### Redis Setup (At-Least-Once Delivery) Source: https://context7.com/kirimatt/goncordia/llms.txt Initializes a Redis driver for at-least-once delivery using Pub/Sub notifications. Pings Redis to verify connectivity. Note that EnqueueTx is not supported; use Enqueue instead. ```go // --- Redis (at-least-once, Pub/Sub notifications) --- import redisdriver "github.com/kirimatt/goncordia/driver/redis" rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"}) d := redisdriver.New(rdb) d.Migrate(ctx) // pings Redis to verify connectivity // Note: EnqueueTx is not supported; use Enqueue (post-commit pattern) instead. ``` -------------------------------- ### Quick Start with Redis Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initialize the Redis driver and Goncordia client. Enqueues a job using the post-commit pattern as `EnqueueTx` is not supported due to lack of rollback guarantees. ```go import ( redisdriver "github.com/kirimatt/goncordia/driver/redis" "github.com/redis/go-redis/v9" ) rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"}) d := redisdriver.New(rdb) d.Migrate(ctx) // pings Redis to verify connectivity client := redisdriver.NewClient(d, goncordia.ClientConfig{}) client.Enqueue(ctx, SendEmailArgs{To: "user@example.com", Subject: "Welcome"}, nil) // EnqueueTx is not supported on the Redis driver: // there is no rollback guarantee. Use Enqueue (post-commit pattern) instead. ``` -------------------------------- ### Install Amazon DynamoDB Adapter Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the Amazon DynamoDB adapter for Goncordia. ```bash go get github.com/kirimatt/goncordia/driver/dynamodb github.com/aws/aws-sdk-go-v2/service/dynamodb ``` -------------------------------- ### Install Goncordia Core and Drivers Source: https://context7.com/kirimatt/goncordia/llms.txt Install the core goncordia module and select the driver for your specific backend database. ```bash # Core module go get github.com/kirimatt/goncordia # Pick one driver: go get github.com/kirimatt/goncordia/driver/pgxv5 # PostgreSQL via pgx v5 go get github.com/kirimatt/goncordia/driver/stdlib # PostgreSQL / MySQL / SQLite via database/sql go get github.com/kirimatt/goncordia/driver/gorm # gorm adapter go get github.com/kirimatt/goncordia/driver/bun # bun adapter go get github.com/kirimatt/goncordia/driver/mongodb # MongoDB (replica set required) go get github.com/kirimatt/goncordia/driver/redis # Redis (at-least-once) go get github.com/kirimatt/goncordia/driver/cassandra # Cassandra / ScyllaDB go get github.com/kirimatt/goncordia/driver/clickhouse # ClickHouse go get github.com/kirimatt/goncordia/driver/dynamodb # Amazon DynamoDB go get github.com/kirimatt/goncordia/driver/firestore # Cloud Firestore ``` -------------------------------- ### Quick Start with Cassandra / ScyllaDB Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initialize the Cassandra/ScyllaDB driver and Goncordia client. Jobs are enqueued using `Enqueue` as `EnqueueTx` offers no rollback guarantee. Idempotent workers and unique job options are recommended for deduplication. ```go import ( cassandradriver "github.com/kirimatt/goncordia/driver/cassandra" "github.com/gocql/gocql" ) cluster := gocql.NewCluster("localhost") cluster.Keyspace = "myapp" // keyspace must already exist session, _ := cluster.CreateSession() defer session.Close() d := cassandradriver.New(session) d.Migrate(ctx) // creates tables (idempotent) client := cassandradriver.NewClient(d, goncordia.ClientConfig{}) client.Enqueue(ctx, SendEmailArgs{To: "user@example.com", Subject: "Welcome"}, nil) // EnqueueTx is identical to Enqueue on Cassandra — no rollback guarantee. // Use idempotent workers and unique job options for deduplication. ``` -------------------------------- ### Quick Start with GORM Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initialize the GORM driver and Goncordia client. Demonstrates transactional inserts where a job is enqueued atomically with a GORM record. ```go import ( gormdriver "github.com/kirimatt/goncordia/driver/gorm" "gorm.io/gorm" ) d, _ := gormdriver.New(db) // db is *gorm.DB d.Migrate(ctx) client := gormdriver.NewClient(d, goncordia.ClientConfig{}) db.Transaction(func(tx *gorm.DB) error { tx.Create(&order) client.EnqueueTx(ctx, tx, SendConfirmationArgs{OrderID: order.ID}, nil) return nil // commit — job appears atomically with the order }) ``` -------------------------------- ### Install Standard Library Drivers Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the standard library drivers for Goncordia, which support PostgreSQL, MySQL, and SQLite. ```bash # PostgreSQL / MySQL / SQLite via database/sql go get github.com/kirimatt/goncordia/driver/stdlib ``` -------------------------------- ### Start a Worker Pool in Go Source: https://github.com/kirimatt/goncordia/blob/main/CLAUDE.md Initialize and start a worker pool using a specific driver. Configure queues, concurrency, and poll interval. The `Start` method blocks; use `wp.Stop()` or context cancellation to gracefully shut down. ```go wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default", "critical"}, Concurrency: 10, PollInterval: 500 * time.Millisecond, }) go wp.Start(ctx) // blocks; cancel ctx or call wp.Stop() to drain ``` -------------------------------- ### PostgreSQL Setup with pgx v5 Source: https://context7.com/kirimatt/goncordia/llms.txt Initializes a PostgreSQL driver using pgx v5 for LISTEN/NOTIFY, SKIP LOCKED, and advisory locks. Requires a database connection pool and sets up a client and worker pool. ```go // --- PostgreSQL via pgx v5 (LISTEN/NOTIFY, SKIP LOCKED, advisory locks) --- import pgxdriver "github.com/kirimatt/goncordia/driver/pgxv5" pool, _ := pgxpool.New(ctx, os.Getenv("DATABASE_URL")) d := pgxdriver.New(pool) d.Migrate(ctx) client := pgxdriver.NewClient(d, goncordia.ClientConfig{}) wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{Queues: []string{"default"}, Concurrency: 10}) ``` -------------------------------- ### Install PostgreSQL Driver (pgx v5) Source: https://github.com/kirimatt/goncordia/blob/main/README.md Install the PostgreSQL driver for Goncordia using pgx v5, along with the pgx library itself. ```bash # PostgreSQL via pgx v5 go get github.com/kirimatt/goncordia/driver/pgxv5 github.com/jackc/pgx/v5 ``` -------------------------------- ### GORM Adapter Setup and Transactional Enqueue Source: https://context7.com/kirimatt/goncordia/llms.txt Integrates Goncordia with GORM. Initializes the driver with a *gorm.DB instance and demonstrates enqueuing a job within a GORM transaction. ```go // --- gorm adapter --- import gormdriver "github.com/kirimatt/goncordia/driver/gorm" d, _ := gormdriver.New(db) // db is *gorm.DB d.Migrate(ctx) db.Transaction(func(tx *gorm.DB) error { tx.Create(&order) client.EnqueueTx(ctx, tx, SendEmailArgs{OrderID: order.ID}, nil) return nil }) ``` -------------------------------- ### Start a Worker Pool with Goncordia Source: https://context7.com/kirimatt/goncordia/llms.txt Creates a pool of goroutines to fetch and process jobs. Call `Start(ctx)` to begin processing and `Stop()` for graceful shutdown. Ensure context is cancelled to stop the pool. ```go import ( "github.com/kirimatt/goncordia" pgxdriver "github.com/kirimatt/goncordia/driver/pgxv5" ) wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default", "email", "critical"}, Concurrency: 20, PollInterval: 500 * time.Millisecond, // fallback when push notifications are unavailable ShutdownTimeout: 30 * time.Second, RetryPolicy: core.ExponentialRetry{Base: time.Second, Max: time.Hour}, }) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) deferr cancel() go func() { <-ctx.Done() wp.Stop() // drain in-flight jobs gracefully }() if err := wp.Start(ctx); err != nil && !errors.Is(err, context.Canceled) { log.Fatal(err) } ``` -------------------------------- ### SQLite Setup with database/sql (Single Writer) Source: https://context7.com/kirimatt/goncordia/llms.txt Configures a SQLite driver using database/sql, specifically setting MaxOpenConns to 1 to enforce a single writer. This is crucial for SQLite's write concurrency limitations. ```go // SQLite — single writer required: db, _ := sql.Open("sqlite", "./jobs.db") db.SetMaxOpenConns(1) d := stdlibdriver.New(db, stdlibdriver.SQLite) d.Migrate(ctx) ``` -------------------------------- ### Run end-to-end flow in memory Source: https://github.com/kirimatt/goncordia/blob/main/README.md Execute an end-to-end flow in memory by setting up a registry, registering workers, and starting a worker pool. ```go registry := core.NewRegistry() core.RegisterWorker(registry, emailWorker, core.WorkerOpts{Queue: "default"}) client, tracker := gontest.NewClient(t) pool := tracker.NewWorkerPool(registry, goncordia.WorkerConfig{ Queues: []string{"default"}, Concurrency: 2, }) runCtx, cancel := context.WithCancel(ctx) deferr cancel() go pool.Start(runCtx) // enqueue and wait for processed.Load() >= 1 ... pool.Stop() ``` -------------------------------- ### Custom Driver Implementation Source: https://github.com/kirimatt/goncordia/blob/main/README.md Implement the `driver.Driver` interface to create a custom driver for Goncordia. This example shows the basic structure and required methods. ```go type MyDriver struct{} func (d *MyDriver) Name() string { return "mydb" } func (d *MyDriver) Capabilities() driver.Capabilities { return driver.Capabilities{NativeTx: true} } func (d *MyDriver) Executor() driver.Executor { return &myExecutor{} } func (d *MyDriver) UnwrapTx(tx MyTx) driver.ExecutorTx { return &myTxExecutor{tx: tx} } func (d *MyDriver) Listener() driver.Listener { return nil } // nil = polling fallback func (d *MyDriver) Close() error { return nil } ``` -------------------------------- ### NewWorkerPool Source: https://context7.com/kirimatt/goncordia/llms.txt Creates a pool of goroutines to fetch and process jobs. Use `Start(ctx)` to begin processing and `Stop()` for graceful shutdown. ```APIDOC ## `goncordia.NewWorkerPool` — Starting a worker pool `NewWorkerPool[TTx]` creates a pool of goroutines that fetch and process jobs. Call `Start(ctx)` to begin processing — it blocks until the context is cancelled. Call `Stop()` for graceful shutdown. ```go import ( "github.com/kirimatt/goncordia" pgxdriver "github.com/kirimatt/goncordia/driver/pgxv5" ) wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default", "email", "critical"}, Concurrency: 20, PollInterval: 500 * time.Millisecond, // fallback when push notifications are unavailable ShutdownTimeout: 30 * time.Second, RetryPolicy: core.ExponentialRetry{Base: time.Second, Max: time.Hour}, }) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) deferr cancel() go func() { <-ctx.Done() wp.Stop() // drain in-flight jobs gracefully }() if err := wp.Start(ctx); err != nil && !errors.Is(err, context.Canceled) { log.Fatal(err) } ``` ``` -------------------------------- ### Adapt Function to Schedule Interface Source: https://github.com/kirimatt/goncordia/blob/main/README.md Use `core.ScheduleFunc` to adapt any function to the `Schedule` interface. This example shows how to create a schedule that runs jobs only during business hours. ```go // core.ScheduleFunc adapts any function to the Schedule interface. sched := core.ScheduleFunc(func(last time.Time) time.Time { if last.IsZero() { return time.Time{} // run immediately on first tick } // Business-hours only: next run at 09:00 the following day next := last.Add(24 * time.Hour) next = time.Date(next.Year(), next.Month(), next.Day(), 9, 0, 0, 0, next.Location()) return next }) ``` -------------------------------- ### Set Up Periodic Cron Jobs Source: https://github.com/kirimatt/goncordia/blob/main/README.md Initializes a CronScheduler to enqueue jobs on a defined schedule. This example sets up two periodic jobs: one hourly cleanup and one daily report, with the report job assigned to a low-priority queue. ```go import "github.com/kirimatt/goncordia/core" cs := goncordia.NewCronScheduler(d, []goncordia.PeriodicJob{ { Schedule: core.Every(time.Hour), Args: CleanupArgs{}, }, { Schedule: core.Every(24 * time.Hour), Args: ReportArgs{}, Opts: &core.InsertOpts{Queue: "low-priority"}, }, }, goncordia.CronConfig{ TickInterval: time.Second, // how often to check for due jobs }) go cs.Start(ctx) // blocks; cancel ctx to stop go wp.Start(ctx) // worker pool processes the enqueued jobs ``` -------------------------------- ### Custom Retry Policy Implementation Source: https://github.com/kirimatt/goncordia/blob/main/README.md Implement a custom retry policy by defining a struct and the `NextRetryAt` method. This example retries jobs based on the attempt number multiplied by one minute. ```go import "github.com/kirimatt/goncordia/internal/clock" type MyPolicy struct{} func (MyPolicy) NextRetryAt(attempt int, err error, clk clock.Clock) time.Time { return clk.Now().Add(time.Duration(attempt) * time.Minute) } ``` -------------------------------- ### Implement Logging Job Middleware in Go Source: https://context7.com/kirimatt/goncordia/llms.txt This middleware logs the start and finish times of job executions, including job details and any errors. It wraps the next job handler in the chain. ```go import ( "log/slog" "github.com/kirimatt/goncordia" "github.com/kirimatt/goncordia/core" ) // Logging middleware — logs start/finish with duration. loggingMiddleware := func(ctx context.Context, job *core.RawJob, next func(context.Context, *core.RawJob) error) error { start := time.Now() slog.InfoContext(ctx, "job started", "kind", job.Kind, "id", job.ID, "attempt", job.AttemptNum, ) err := next(ctx, job) slog.InfoContext(ctx, "job finished", "kind", job.Kind, "id", job.ID, "duration_ms", time.Since(start).Milliseconds(), "error", err, ) return err } wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default"}, Concurrency: 10, Middleware: []goncordia.JobMiddleware{loggingMiddleware}, }) ``` -------------------------------- ### Initialize SQLite Driver for Testing Source: https://github.com/kirimatt/goncordia/blob/main/README.md Sets up a connection to a local SQLite database, suitable for testing. It configures the database to have a single open connection, enforcing a single writer. ```go import ( _ "modernc.org/sqlite" stdlibdriver "github.com/kirimatt/goncordia/driver/stdlib" ) db, _ := sql.Open("sqlite", "./jobs.db") db.SetMaxOpenConns(1) // SQLite: single writer d := stdlibdriver.New(db, stdlibdriver.SQLite) d.Migrate(ctx) ``` -------------------------------- ### Initialize ClickHouse Driver and Enqueue Job Source: https://github.com/kirimatt/goncordia/blob/main/README.md Sets up a connection to ClickHouse and creates a driver instance. Jobs enqueued are at-least-once delivery and workers should be idempotent. Best suited for high-throughput analytics pipelines. ```go import ( clickhousedriver "github.com/kirimatt/goncordia/driver/clickhouse" "github.com/ClickHouse/clickhouse-go/v2" ) conn, _ := clickhouse.Open(&clickhouse.Options{ Addr: []string{"localhost:9000"}, Auth: clickhouse.Auth{Database: "myapp"}, }) d := clickhousedriver.New(conn) d.Migrate(ctx) // creates ReplacingMergeTree tables (idempotent) client := clickhousedriver.NewClient(d, goncordia.ClientConfig{}) client.Enqueue(ctx, SendEmailArgs{To: "user@example.com", Subject: "Welcome"}, nil) // ClickHouse has no transactions. Jobs use at-least-once delivery — workers // should be idempotent. Best suited for high-throughput analytics pipelines. ``` -------------------------------- ### Run Go Benchmarks Source: https://github.com/kirimatt/goncordia/blob/main/README.md Command to execute benchmarks for the Go project. Use -benchmem to include memory allocation statistics and -benchtime to set the duration for each benchmark. ```bash go test ./bench/... -bench=. -benchmem -benchtime=5s -timeout=15m ``` -------------------------------- ### Transactional Insert with MongoDB SessionContext Source: https://context7.com/kirimatt/goncordia/llms.txt Demonstrates a transactional insert operation in MongoDB using `mongo.SessionContext`. It starts a transaction, inserts an order, enqueues a job within the transaction, and commits. ```go // Transactional insert via mongo.SessionContext: mc.UseSession(ctx, func(sc mongo.SessionContext) error { sc.StartTransaction() db.Collection("orders").InsertOne(sc, order) client.EnqueueTx(sc, sc, SendEmailArgs{OrderID: order.ID}, nil) return sc.CommitTransaction(sc) }) ``` -------------------------------- ### Initialize Firestore Driver and Enqueue Job Transactionally Source: https://github.com/kirimatt/goncordia/blob/main/README.md Connects to Google Cloud Firestore and sets up the Goncordia driver. Migration is a no-op; a composite index must be created manually. Jobs can be enqueued atomically with other business writes using transactions. ```go import ( "cloud.google.com/go/firestore" firestoredriver "github.com/kirimatt/goncordia/driver/firestore" ) fsClient, _ := firestore.NewClient(ctx, "my-gcp-project") d := firestoredriver.New(fsClient) // Migrate is a no-op; create composite index in Firebase console: // collection: goncordia_jobs, fields: queue (ASC), state (ASC), run_at (ASC) d.Migrate(ctx) client := firestoredriver.NewClient(d, goncordia.ClientConfig{}) // Transactional — job is enqueued atomically with business writes: fsClient.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error { tx.Create(orders.Doc(id), orderData) _, err := client.EnqueueTx(ctx, tx, SendConfirmationArgs{OrderID: id}, nil) return err }) ``` -------------------------------- ### In-Memory Driver for Testing Source: https://github.com/kirimatt/goncordia/blob/main/README.md Set up the in-memory driver for deterministic testing. This configuration uses a mock clock and avoids external dependencies like databases or Docker. ```go import ( "github.com/kirimatt/goncordia/driver/memory" "github.com/kirimatt/goncordia/internal/clock" ) clk := clock.NewMock(time.Now()) d := memory.New(memory.WithClock(clk)) client := goncordia.NewClient[memory.NoTx](d, goncordia.ClientConfig{}) wp := goncordia.NewWorkerPool[memory.NoTx](d, registry, goncordia.WorkerConfig{Clock: clk}) go wp.Start(ctx) clk.Advance(time.Hour) // trigger scheduled jobs instantly jobs := d.AllJobs() // inspect state without a real database ``` -------------------------------- ### Create Goncordia Client with pgx driver Source: https://context7.com/kirimatt/goncordia/llms.txt Initializes a Goncordia client using the pgx v5 driver for PostgreSQL. Ensures the necessary goncordia_jobs table is migrated before creating the client. ```go import ( "github.com/kirimatt/goncordia" pgxdriver "github.com/kirimatt/goncordia/driver/pgxv5" "github.com/jackc/pgx/v5/pgxpool" ) pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL")) if err != nil { log.Fatal(err) } d := pgxdriver.New(pool) if err := d.Migrate(ctx); err != nil { // creates goncordia_jobs table log.Fatal(err) } client := pgxdriver.NewClient(d, goncordia.ClientConfig{ DefaultQueue: "default", }) ``` -------------------------------- ### Configure job insertion with core.InsertOpts Source: https://context7.com/kirimatt/goncordia/llms.txt Specifies advanced options for job enqueuing, including queue, priority, scheduled run time, deduplication, retry limits, and tags. Useful for fine-grained control over job execution. ```go maxRetry := 3 timeout := 45 * time.Second _, err := client.Enqueue(ctx, ProcessPaymentArgs{PaymentID: "pay_abc"}, &core.InsertOpts{ Queue: "critical", Priority: 100, // processed before lower-priority jobs RunAt: time.Now().Add(5 * time.Minute), // schedule for future execution UniqueOpts: &core.UniqueOpts{ ByArgs: true, ByQueue: true, ByPeriod: time.Hour, // one payment-processing job per payment per hour }, MaxRetry: &maxRetry, // override worker default of 3 Timeout: &timeout, // 45s execution timeout Tags: []string{"payment", "user:99"}, }) ``` -------------------------------- ### Initialize DynamoDB Driver and Enqueue Job Source: https://github.com/kirimatt/goncordia/blob/main/README.md Configures the AWS SDK for DynamoDB and initializes the Goncordia driver. Jobs are processed with at-least-once delivery. Unique-key deduplication uses PutItem with attribute_not_exists condition. Jobs are claimed with conditional UpdateItem, making it safe for concurrent workers. ```go import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/dynamodb" dynamodbdriver "github.com/kirimatt/goncordia/driver/dynamodb" ) cfg, _ := config.LoadDefaultConfig(ctx) svc := dynamodb.NewFromConfig(cfg) d := dynamodbdriver.New(svc) d.Migrate(ctx) // creates goncordia_jobs + goncordia_uniq + goncordia_queues + goncordia_leaders (idempotent) client := dynamodbdriver.NewClient(d, goncordia.ClientConfig{}) client.Enqueue(ctx, SendEmailArgs{To: "user@example.com", Subject: "Welcome"}, nil) // DynamoDB has no cross-table transactions. EnqueueTx behaves like Enqueue. // Unique-key deduplication uses PutItem with attribute_not_exists condition. // Jobs are claimed with conditional UpdateItem — safe for concurrent workers. ``` -------------------------------- ### Enqueue Job with Advanced Options Source: https://github.com/kirimatt/goncordia/blob/main/README.md Demonstrates enqueuing a job with various options including queue override, priority setting, delayed execution, unique job deduplication, and custom retry counts and tags. ```go maxRetry := 3 client.Enqueue(ctx, SendEmailArgs{To: "user@example.com", Subject: "Welcome"}, &core.InsertOpts{ Queue: "critical", // override default queue Priority: 10, // higher = processed first RunAt: time.Now().Add(time.Hour), // schedule for later UniqueOpts: &core.UniqueOpts{ // deduplicate ByArgs: true, ByQueue: true, }, MaxRetry: &maxRetry, Tags: []string{"user:42"}, }) ``` -------------------------------- ### Configure Job Enqueue Options in Go Source: https://github.com/kirimatt/goncordia/blob/main/CLAUDE.md Customize job enqueuing with `InsertOpts`, specifying queue, priority, run time, max retries, and uniqueness constraints. ```go maxRetry := 3 client.Enqueue(ctx, args, &core.InsertOpts{ Queue: "critical", Priority: 10, RunAt: time.Now().Add(time.Hour), MaxRetry: &maxRetry, UniqueOpts: &core.UniqueOpts{ByArgs: true, ByQueue: true}, }) ``` -------------------------------- ### Implementing a Custom Driver Interface Source: https://context7.com/kirimatt/goncordia/llms.txt Defines the structure for a custom storage driver by implementing the driver.Driver interface. This involves defining transaction types, capabilities, and methods for job insertion and execution. ```go import "github.com/kirimatt/goncordia/driver" // MyTx is the transaction type for your custom backend. type MyTx struct{ /* ... */ } type MyDriver struct{ db *MyDBClient } func (d *MyDriver) Name() string { return "mydb" } func (d *MyDriver) Capabilities() driver.Capabilities { return driver.Capabilities{ NativeTx: true, // supports EnqueueTx SkipLocked: false, UniqueJobs: true, } } func (d *MyDriver) Executor() driver.Executor { return &myExecutor{db: d.db} } func (d *MyDriver) UnwrapTx(tx MyTx) driver.ExecutorTx { return &myTxExecutor{tx: tx} } func (d *MyDriver) Listener() driver.Listener { return nil } // nil = polling fallback func (d *MyDriver) Close() error { return d.db.Close() } // myExecutor must implement the 14-method baseExecutor interface. // See driver/memory/memory.go for a minimal complete reference implementation. type myExecutor struct{ db *MyDBClient } func (e *myExecutor) JobInsertMany(ctx context.Context, params []driver.JobInsertParams) ([]driver.JobInsertResult, error) { // insert rows, handle unique key deduplication return results, nil } // ... implement remaining 13 methods ... ``` -------------------------------- ### Set up a Cron Scheduler for Periodic Jobs Source: https://context7.com/kirimatt/goncordia/llms.txt Enqueues jobs on a repeating schedule, intended to be paired with a `WorkerPool`. Uses `core.Every` for simple intervals or `core.ScheduleFunc` for custom logic. ```go import ( "github.com/kirimatt/goncordia" "github.com/kirimatt/goncordia/core" ) cs := goncordia.NewCronScheduler(d, []goncordia.PeriodicJob{ { Schedule: core.Every(time.Hour), Args: CleanupArgs{}, }, { Schedule: core.Every(24 * time.Hour), Args: DailyReportArgs{}, Opts: &core.InsertOpts{ Queue: "reports", UniqueOpts: &core.UniqueOpts{ByArgs: true, ByPeriod: 24 * time.Hour}, }, }, { // Business-hours only: fire at 09:00 each day. Schedule: core.ScheduleFunc(func(last time.Time) time.Time { if last.IsZero() { return time.Time{} // run immediately on first tick } next := last.Add(24 * time.Hour) return time.Date(next.Year(), next.Month(), next.Day(), 9, 0, 0, 0, next.Location()) }), Args: MorningDigestArgs{}, }, }, goncordia.CronConfig{ TickInterval: time.Second, }) ctx, cancel := context.WithCancel(context.Background()) deferr cancel() go cs.Start(ctx) // blocks; cancel ctx to stop go wp.Start(ctx) // worker pool processes enqueued jobs ``` -------------------------------- ### Test job enqueuing with gontest Source: https://github.com/kirimatt/goncordia/blob/main/README.md Assert that business logic enqueues the correct jobs. Requires a client and tracker from gontest. ```go func TestPlaceOrder_EnqueuesConfirmationEmail(t *testing.T) { ctx := context.Background() client, tracker := gontest.NewClient(t) _ = PlaceOrder(ctx, client, "order-123") // calls client.Enqueue internally jobs := gontest.RequireEnqueued[SendEmailArgs](t, tracker, 1) if jobs[0].Args.OrderID != "order-123" { t.Errorf("unexpected order ID: %s", jobs[0].Args.OrderID) } } ``` -------------------------------- ### No Retry Policy Source: https://github.com/kirimatt/goncordia/blob/main/README.md Configure a policy that discards jobs immediately without retrying. ```go core.NoRetry{} ``` -------------------------------- ### Configure Periodic Jobs with Cron Scheduler in Go Source: https://github.com/kirimatt/goncordia/blob/main/CLAUDE.md Set up periodic jobs using `goncordia.NewCronScheduler`. Define schedules using `core.Every` and configure tick intervals for the scheduler. ```go cs := goncordia.NewCronScheduler(d, []goncordia.PeriodicJob{ {Schedule: core.Every(time.Hour), Args: CleanupArgs{}}, }, goncordia.CronConfig{TickInterval: time.Second}) go cs.Start(ctx) ``` -------------------------------- ### Integrate OpenTelemetry Middleware with Goncordia Source: https://context7.com/kirimatt/goncordia/llms.txt This middleware provides OpenTelemetry tracing and metrics for each job execution. Configure it with your OpenTelemetry tracer and meter providers. It can be combined with other middleware like logging. ```go import ( "go.opentelemetry.io/otel/sdk/trace" otelgoncordia "github.com/kirimatt/goncordia/otel" "github.com/kirimatt/goncordia" ) // Set up your OTel SDK (tracing + metrics) as usual, then: tp := trace.NewTracerProvider(trace.WithBatcher(exporter)) mp := metric.NewMeterProvider(metric.WithReader(reader)) wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default"}, Concurrency: 10, Middleware: []goncordia.JobMiddleware{ otelgoncordia.NewMiddleware( otelgoncordia.WithTracerProvider(tp), otelgoncordia.WithMeterProvider(mp), ), loggingMiddleware, // combine with other middleware }, }) // Each processed job produces: // Span: "goncordia.process" with attributes goncordia.job.kind, .queue, .id, .attempt // Histogram: goncordia.job.duration{kind, queue, status="ok"|"error"} // Counter: goncordia.job.count{kind, queue, status="ok"|"error"} ``` -------------------------------- ### Test scheduled jobs with mock clock Source: https://github.com/kirimatt/goncordia/blob/main/README.md Test scheduled jobs using a controllable mock clock. Enqueue jobs with specific run times and advance the clock to test execution. ```go clk := gontest.NewMockClock() client, tracker := gontest.NewClientWithClock(t, clk) client.Enqueue(ctx, ReminderArgs{UserID: "u1"}, &core.InsertOpts{ RunAt: clk.Now().Add(24 * time.Hour), }) // Job exists but is not yet available: gontest.RequireEnqueued[ReminderArgs](t, tracker, 1) // Advance past the scheduled time: clk.Advance(25 * time.Hour) // now start the pool — the job will be picked up immediately ``` -------------------------------- ### Exponential Retry Policy Source: https://github.com/kirimatt/goncordia/blob/main/README.md Configure an exponential backoff retry policy. The delay increases exponentially (1s, 2s, 4s, ...) and is capped at 24 hours. ```go core.ExponentialRetry{Base: time.Second, Max: 24 * time.Hour} ``` -------------------------------- ### client.EnqueueMany / client.EnqueueManyTx Source: https://context7.com/kirimatt/goncordia/llms.txt `EnqueueMany` inserts multiple jobs in a single batch call. `EnqueueManyTx` does the same inside a transaction. Both accept a single `*core.InsertOpts` applied to all jobs. ```APIDOC ## client.EnqueueMany / client.EnqueueManyTx ### Description Inserts multiple jobs in a single batch call, either non-transactionally (`EnqueueMany`) or within a transaction (`EnqueueManyTx`). A single `*core.InsertOpts` applies to all jobs in the batch. ### Method POST (assumed, for batch insertion) ### Endpoint `/jobs/batch` (assumed for `EnqueueMany`) `/jobs/batch/tx` (assumed for `EnqueueManyTx`) ### Parameters #### Query Parameters - **ctx** (context.Context) - Required - The context for the request. - **tx** (interface{}) - Required for `EnqueueManyTx` - The transaction object. #### Request Body - **args** ([]core.JobArgs) - Required - A slice of job arguments. - **opts** (*core.InsertOpts) - Optional - Options applied to all jobs in the batch. ### Request Example ```go // Batch-enqueue a report job for each user. userIDs := []string{"u1", "u2", "u3", "u4", "u5"} args := make([]core.JobArgs, len(userIDs)) for i, id := range userIDs { args[i] = GenerateReportArgs{UserID: id} } results, err := client.EnqueueMany(ctx, args, &core.InsertOpts{ Queue: "reports", Priority: 1, UniqueOpts: &core.UniqueOpts{ ByArgs: true, ByQueue: true, ByPeriod: 24 * time.Hour, // deduplicate within a rolling 24-hour window }, }) ``` ### Response #### Success Response (200) - **results** ([]core.EnqueueResult) - A slice of results, one for each enqueued job. - **err** (error) - An error if the batch operation failed. #### Response Example ```json [ { "Job": { "ID": "job_batch_1" }, "UniqueSkip": false }, { "Job": { "ID": "job_batch_2" }, "UniqueSkip": true } ] ``` ``` -------------------------------- ### Define Job Arguments with core.JobArgs Source: https://context7.com/kirimatt/goncordia/llms.txt Define job payloads as structs implementing `core.JobArgs`. The `Kind()` method must return a unique identifier for routing. Args are automatically JSON-serialized. ```go import "github.com/kirimatt/goncordia/core" // SendEmailArgs is the job payload for sending confirmation emails. type SendEmailArgs struct { To string `json:"to"` Subject string `json:"subject"` OrderID string `json:"order_id"` } // Kind must return a stable, unique identifier for this job type. func (SendEmailArgs) Kind() string { return "send_email" } // ResizeImageArgs demonstrates a second job type in the same application. type ResizeImageArgs struct { ImageID string `json:"image_id"` Width int `json:"width"` Height int `json:"height"` } func (ResizeImageArgs) Kind() string { return "resize_image" } ``` -------------------------------- ### Configure worker pool with OpenTelemetry middleware Source: https://github.com/kirimatt/goncordia/blob/main/README.md Integrate OpenTelemetry middleware into the worker pool configuration. Optionally provide custom TracerProvider and MeterProvider. ```go import otelgoncordia "github.com/kirimatt/goncordia/otel" wp := pgxdriver.NewWorkerPool(d, registry, goncordia.WorkerConfig{ Queues: []string{"default"}, Concurrency: 10, Middleware: []goncordia.JobMiddleware{ otelgoncordia.NewMiddleware( // optional — defaults to otel.GetTracerProvider() / otel.GetMeterProvider() otelgoncordia.WithTracerProvider(tp), otelgoncordia.WithMeterProvider(mp), ), }, }) ``` -------------------------------- ### Fixed Delay Retry Policy Source: https://github.com/kirimatt/goncordia/blob/main/README.md Configure a fixed delay retry policy. Jobs will be retried with a consistent delay of 30 seconds. ```go core.FixedRetry{Delay: 30 * time.Second} ``` -------------------------------- ### core.InsertOpts Source: https://context7.com/kirimatt/goncordia/llms.txt `InsertOpts` controls scheduling, priority, deduplication, retry limits, and tagging for a single enqueue call. ```APIDOC ## core.InsertOpts ### Description Options to control the scheduling, priority, deduplication, retry limits, and tagging for job enqueuing. ### Fields - **Queue** (string) - Optional - The queue to place the job in. Overrides the default queue. - **Priority** (int) - Optional - The priority of the job. Higher values are processed first. - **RunAt** (time.Time) - Optional - The specific time at which the job should be executed. - **UniqueOpts** (*core.UniqueOpts) - Optional - Options for job deduplication. - **ByArgs** (bool) - If true, skip if an identical job with the same arguments is already pending. - **ByQueue** (bool) - If true, consider the queue when checking for duplicates. - **ByPeriod** (time.Duration) - Deduplicate within a rolling time window. - **MaxRetry** (*int) - Optional - The maximum number of times to retry the job. Overrides worker defaults. - **Timeout** (*time.Duration) - Optional - The execution timeout for the job. - **Tags** ([]string) - Optional - Tags to associate with the job for filtering or routing. ### Request Example ```go maxRetry := 3 timeout := 45 * time.Second _, err := client.Enqueue(ctx, ProcessPaymentArgs{PaymentID: "pay_abc"}, &core.InsertOpts{ Queue: "critical", Priority: 100, RunAt: time.Now().Add(5 * time.Minute), UniqueOpts: &core.UniqueOpts{ ByArgs: true, ByQueue: true, ByPeriod: time.Hour, // one payment-processing job per payment per hour }, MaxRetry: &maxRetry, // override worker default of 3 Timeout: &timeout, // 45s execution timeout Tags: []string{"payment", "user:99"}, }) ``` ``` -------------------------------- ### Test Job Enqueuing with gontest Source: https://context7.com/kirimatt/goncordia/llms.txt Uses gontest.NewClient to create an in-memory client and tracker. Asserts that a specific job type is enqueued with the correct arguments using gontest.RequireEnqueued. ```go import ( "testing" "context" "github.com/kirimatt/goncordia/gontest" "github.com/kirimatt/goncordia/core" ) func TestPlaceOrder_EnqueuesConfirmationEmail(t *testing.T) { ctx := context.Background() client, tracker := gontest.NewClient(t) if err := PlaceOrder(ctx, client, "ord-123", "alice@example.com"); err != nil { t.Fatal(err) } // Assert exactly one SendEmailArgs job was enqueued. jobs := gontest.RequireEnqueued[SendEmailArgs](t, tracker, 1) if jobs[0].Args.OrderID != "ord-123" { t.Errorf("wrong order ID: got %s", jobs[0].Args.OrderID) } } ``` -------------------------------- ### Define Job Arguments in Go Source: https://github.com/kirimatt/goncordia/blob/main/CLAUDE.md Implement `core.JobArgs` for custom job types. Ensure the type is JSON-serializable and has a `Kind()` method returning a unique string identifier. ```go type SendEmailArgs struct { To string `json:"to"` Subject string `json:"subject"` } func (SendEmailArgs) Kind() string { return "send_email" } ```