### Install goqite Library Source: https://github.com/maragudk/goqite/blob/main/README.md Use 'go get' to install the goqite library. This command fetches and installs the library and its dependencies. ```shell go get maragu.dev/goqite ``` -------------------------------- ### Queue Operations in Go Source: https://github.com/maragudk/goqite/blob/main/README.md Demonstrates basic queue operations including setup, sending, receiving, extending message visibility, and deleting messages. Ensure the database and schema are set up before use. ```go package main import ( "context" "database/sql" "fmt" "log/slog" "os" "time" _ "github.com/mattn/go-sqlite3" "maragu.dev/goqite" ) func main() { log := slog.Default() // Setup the db db, err := sql.Open("sqlite3", ":memory:?_journal=WAL&_timeout=5000&_fk=true") if err != nil { log.Info("Error opening db", "error", err) return } db.SetMaxOpenConns(1) db.SetMaxIdleConns(1) // Setup the schema schema, err := os.ReadFile("schema_sqlite.sql") if err != nil { log.Info("Error reading schema:", "error", err) return } if _, err := db.Exec(string(schema)); err != nil { log.Info("Error executing schema:", "error", err) return } // Create a new queue named "jobs". // You can also customize the message redelivery timeout and maximum receive count, // but here, we use the defaults. q := goqite.New(goqite.NewOpts{ DB: db, Name: "jobs", }) // Send a message to the queue. // Note that the body is an arbitrary byte slice, so you can decide // what kind of payload you have. You can also set a message delay. err = q.Send(context.Background(), goqite.Message{ Body: []byte("yo"), }) if err != nil { log.Info("Error sending message", "error", err) return } // Receive a message from the queue, during which time it's not available to // other consumers (until the message timeout has passed). m, err := q.Receive(context.Background()) if err != nil { log.Info("Error receiving message", "error", err) return } fmt.Println(string(m.Body)) // If you need more time for processing the message, you can extend // the message timeout as many times as you want. if err := q.Extend(context.Background(), m.ID, time.Second); err != nil { log.Info("Error extending message timeout", "error", err) return } // Make sure to delete the message, so it doesn't get redelivered. if err := q.Delete(context.Background(), m.ID); err != nil { log.Info("Error deleting message", "error", err) return } } ``` -------------------------------- ### Job Runner with Goqite in Go Source: https://github.com/maragudk/goqite/blob/main/README.md Illustrates setting up and using a job runner to process messages from a Goqite queue. This includes registering job handlers, creating jobs, and starting the runner with a context for graceful shutdown. ```go package main import ( "context" "database/sql" "fmt" "log/slog" "os" "time" _ "github.com/mattn/go-sqlite3" "maragu.dev/goqite" "maragu.dev/goqite/jobs" ) func main() { log := slog.Default() // Setup the db db, err := sql.Open("sqlite3", ":memory:?_journal=WAL&_timeout=5000&_fk=true") if err != nil { log.Info("Error opening db", "error", err) return } db.SetMaxOpenConns(1) db.SetMaxIdleConns(1) // Setup the schema schema, err := os.ReadFile("schema_sqlite.sql") if err != nil { log.Info("Error reading schema:", "error", err) return } if _, err := db.Exec(string(schema)); err != nil { log.Info("Error executing schema:", "error", err) return } // 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: log, 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) } ``` -------------------------------- ### Initialize goqite with PostgreSQL Source: https://github.com/maragudk/goqite/blob/main/README.md Use this snippet to create a goqite queue instance configured for PostgreSQL. Ensure you have imported the PostgreSQL driver and have an active *sql.DB connection. ```go import _ "github.com/jackc/pgx/v5/stdlib" // Create the queue with PostgreSQL flavor q := goqite.New(goqite.NewOpts{ DB: db, // *sql.DB connected to PostgreSQL Name: "jobs", SQLFlavor: goqite.SQLFlavorPostgreSQL, }) ``` -------------------------------- ### Run Goqite Benchmarks Source: https://github.com/maragudk/goqite/blob/main/README.md Execute the benchmark suite for the Goqite library. This command runs tests across different CPU core counts to measure performance. ```shell make benchmark go test -cpu 1,2,4,8,16 -bench=. ``` -------------------------------- ### Run Jobs with Goqite's Job Runner Source: https://github.com/maragudk/goqite/blob/main/docs/index.html Utilizes the `jobs` package to create and run background jobs. This is suitable for processing tasks asynchronously. Configure the runner with a limit, logger, poll interval, and the queue to use. ```go package main import ( "context" "database/sql" "fmt" "log/slog" "os" "time" _ "github.com/mattn/go-sqlite3" "maragu.dev/goqite" "maragu.dev/goqite/jobs" ) func main() { log := slog.Default() // Setup the db db, err := sql.Open("sqlite3", ":memory:?_journal=WAL&_timeout=5000&_fk=true") if err != nil { log.Info("Error opening db", "error", err) return } db.SetMaxOpenConns(1) db.SetMaxIdleConns(1) // Setup the schema schema, err := os.ReadFile("schema_sqlite.sql") if err != nil { log.Info("Error reading schema:", "error", err) return } if _, err := db.Exec(string(schema)); err != nil { log.Info("Error executing schema:", "error", err) return } // 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: log, 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) } ``` -------------------------------- ### Send, Receive, Extend, and Delete Messages with Goqite Source: https://github.com/maragudk/goqite/blob/main/docs/index.html Demonstrates the basic lifecycle of a message in a Goqite queue. Use this for direct message manipulation. Ensure proper error handling for database operations and queue interactions. ```go package main import ( "context" "database/sql" "fmt" "log/slog" "os" "time" _ "github.com/mattn/go-sqlite3" "maragu.dev/goqite" ) func main() { log := slog.Default() // Setup the db db, err := sql.Open("sqlite3", ":memory:?_journal=WAL&_timeout=5000&_fk=true") if err != nil { log.Info("Error opening db", "error", err) return } db.SetMaxOpenConns(1) db.SetMaxIdleConns(1) // Setup the schema schema, err := os.ReadFile("schema_sqlite.sql") if err != nil { log.Info("Error reading schema:", "error", err) return } if _, err := db.Exec(string(schema)); err != nil { log.Info("Error executing schema:", "error", err) return } // Create a new queue named "jobs". // You can also customize the message redelivery timeout and maximum receive count, // but here, we use the defaults. q := goqite.New(goqite.NewOpts{ DB: db, Name: "jobs", }) // Send a message to the queue. // Note that the body is an arbitrary byte slice, so you can decide // what kind of payload you have. You can also set a message delay. err = q.Send(context.Background(), goqite.Message{ Body: []byte("yo"), }) if err != nil { log.Info("Error sending message", "error", err) return } // Receive a message from the queue, during which time it's not available to // other consumers (until the message timeout has passed). m, err := q.Receive(context.Background()) if err != nil { log.Info("Error receiving message", "error", err) return } fmt.Println(string(m.Body)) // If you need more time for processing the message, you can extend // the message timeout as many times as you want. if err := q.Extend(context.Background(), m.ID, time.Second); err != nil { log.Info("Error extending message timeout", "error", err) return } // Make sure to delete the message, so it doesn't get redelivered. if err := q.Delete(context.Background(), m.ID); err != nil { log.Info("Error deleting message", "error", err) return } } ``` -------------------------------- ### PostgreSQL Schema for goqite Source: https://github.com/maragudk/goqite/blob/main/README.md This SQL schema is required for setting up your PostgreSQL database to work with goqite. It includes table definitions, triggers, and necessary extensions. ```sql create extension if not exists pgcrypto; create function update_timestamp() returns trigger as $$ begin new.updated = now(); return new; end; $$ language plpgsql; create table goqite ( id text primary key default ('m_' || encode(gen_random_bytes(16), 'hex')), created timestamptz not null default now(), updated timestamptz not null default now(), queue text not null, body bytea not null, timeout timestamptz not null default now(), received integer not null default 0 ); create trigger goqite_updated_timestamp before update on goqite for each row execute procedure update_timestamp(); create index goqite_queue_created_idx on goqite (queue, created); ``` -------------------------------- ### SQLite Schema for goqite Source: https://github.com/maragudk/goqite/blob/main/README.md This SQL schema is for setting up a SQLite database to work with goqite. It defines the table structure and a trigger for updating timestamps. ```sql create table goqite ( id text primary key default ('m_' || lower(hex(randomblob(16)))), created text not null default (strftime('%Y-%m-%dT%H:%M:%fZ')), updated text not null default (strftime('%Y-%m-%dT%H:%M:%fZ')), queue text not null, body blob not null, timeout text not null default (strftime('%Y-%m-%dT%H:%M:%fZ')), received integer not null default 0 ) strict; create trigger goqite_updated_timestamp after update on goqite begin update goqite set updated = strftime('%Y-%m-%dT%H:%M:%fZ') where id = old.id; end; create index goqite_queue_created_idx on goqite (queue, created); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.