diff --git a/README.md b/README.md index 50971ae..2b8a2fb 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Made in 🇩🇰 by [maragu](https://www.maragu.dk/), maker of [online Go course - Messages are sent to and received from the queue, and are guaranteed to not be redelivered before a timeout occurs. - Support for multiple queues in one table. - Message timeouts can be extended, to support e.g. long-running tasks. +- A job runner abstraction is provided on top of the queue, for your background tasks. - A simple HTTP handler is provided for your convenience. - No non-test dependencies. Bring your own SQLite driver. @@ -45,6 +46,8 @@ func main() { if err != nil { log.Fatalln(err) } + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) if err := goqite.Setup(context.Background(), db); err != nil { log.Fatalln(err) diff --git a/docs/examples/jobs/main.go b/docs/examples/jobs/main.go new file mode 100644 index 0000000..537d75a --- /dev/null +++ b/docs/examples/jobs/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + "database/sql" + "fmt" + "log/slog" + "time" + + _ "github.com/mattn/go-sqlite3" + + "github.com/maragudk/goqite" + "github.com/maragudk/goqite/jobs" +) + +func main() { + log := slog.Default() + + // Setup the db and goqite schema. + db, err := sql.Open("sqlite3", ":memory:?_journal=WAL&_timeout=5000&_fk=true") + if err != nil { + log.Info("Error opening db", "error", err) + } + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) + + if err := goqite.Setup(context.Background(), db); err != nil { + log.Info("Error in setup", "error", err) + } + + // Make a new queue for the jobs. You can have as many of these as you like, just name them differently. + q := goqite.New(goqite.NewOpts{ + DB: db, + Name: "jobs", + }) + + // Make a job runner with a job limit of 1 and a short message poll interval. + r := jobs.NewRunner(jobs.NewRunnerOpts{ + Limit: 1, + Log: slog.Default(), + PollInterval: 10 * time.Millisecond, + Queue: q, + }) + + // Register our "print" job. + r.Register("print", func(ctx context.Context, m []byte) error { + fmt.Println(string(m)) + return nil + }) + + // Create a "print" job with a message. + if err := jobs.Create(context.Background(), q, "print", []byte("Yo")); err != nil { + log.Info("Error creating job", "error", err) + } + + // Stop the job runner after a timeout. + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond) + defer cancel() + + // Start the job runner and see the job run. + r.Start(ctx) +} diff --git a/docs/example.go b/docs/examples/queue/main.go similarity index 97% rename from docs/example.go rename to docs/examples/queue/main.go index 4a017b8..85137d8 100644 --- a/docs/example.go +++ b/docs/examples/queue/main.go @@ -21,6 +21,8 @@ func main() { if err != nil { log.Fatalln(err) } + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) if err := goqite.Setup(context.Background(), db); err != nil { log.Fatalln(err) diff --git a/docs/index.html b/docs/index.html index e0f7f85..30bf403 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,9 @@
$ go get github.com/maragudk/goqite
- package main
@@ -49,6 +51,8 @@ Example
if err != nil {
log.Fatalln(err)
}
+ db.SetMaxOpenConns(1)
+ db.SetMaxIdleConns(1)
if err := goqite.Setup(context.Background(), db); err != nil {
log.Fatalln(err)
@@ -92,11 +96,77 @@ Example
log.Fatalln(err)
}
}
+
+
+ package main
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "log/slog"
+ "time"
+
+ _ "github.com/mattn/go-sqlite3"
+
+ "github.com/maragudk/goqite"
+ "github.com/maragudk/goqite/jobs"
+)
+
+func main() {
+ log := slog.Default()
+
+ // Setup the db and goqite schema.
+ db, err := sql.Open("sqlite3", ":memory:?_journal=WAL&_timeout=5000&_fk=true")
+ if err != nil {
+ log.Info("Error opening db", "error", err)
+ }
+ db.SetMaxOpenConns(1)
+ db.SetMaxIdleConns(1)
+
+ if err := goqite.Setup(context.Background(), db); err != nil {
+ log.Info("Error in setup", "error", err)
+ }
+
+ // Make a new queue for the jobs. You can have as many of these as you like, just name them differently.
+ q := goqite.New(goqite.NewOpts{
+ DB: db,
+ Name: "jobs",
+ })
+
+ // Make a job runner with a job limit of 1 and a short message poll interval.
+ r := jobs.NewRunner(jobs.NewRunnerOpts{
+ Limit: 1,
+ Log: slog.Default(),
+ PollInterval: 10 * time.Millisecond,
+ Queue: q,
+ })
+
+ // Register our "print" job.
+ r.Register("print", func(ctx context.Context, m []byte) error {
+ fmt.Println(string(m))
+ return nil
+ })
+
+ // Create a "print" job with a message.
+ if err := jobs.Create(context.Background(), q, "print", []byte("Yo")); err != nil {
+ log.Info("Error creating job", "error", err)
+ }
+
+ // Stop the job runner after a timeout.
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond)
+ defer cancel()
+
+ // Start the job runner and see the job run.
+ r.Start(ctx)
+}
-
+