Batteries
Four optional infrastructure packages: mq for NATS/JetStream messaging, cache (in-memory by default, redis opt-in), storage for a PgBouncer-safe pgx pool, and client for OTel-instrumented outbound calls. Each is importable on its own; what you do not use is not wired in.
Fetch the module first: go get github.com/yshengliao/gortexa@v0.28.3. Every snippet below is compile-verified against v0.28.3.
NATS-backed pluggable pub/sub. cfg.MQ.Driver selects nats (core, at-most-once) or jetstream (durable, at-least-once, handlers must be idempotent). An empty group_id fans out; a non-empty one load-balances.
import "github.com/yshengliao/gortexa/mq"
pub, sub, err := mq.New(cfg.MQ)if err != nil { return err}defer pub.Close(context.Background()) // ctx is a shutdown budget: on expiry it returns early and the teardown finishes in the backgrounderr = sub.Subscribe(ctx, "orders", func(ctx context.Context, m mq.Message) error { return handle(m.Value)})err = pub.Publish(ctx, "orders", mq.Message{Value: []byte("hello")})Message carries Key / Value / Headers. Two header names are reserved on every driver and rejected at Publish with InvalidArgument: gortexa-key, and anything in the broker’s case-insensitive nats-* namespace (Nats-Msg-Id, Nats-Expected-*, Nats-Rollup, …). You can also call mq.NewNATS / mq.NewJetStream to pick a driver directly.
Process-local in-memory by default; cfg.Cache.Driver: redis opts into a distributed backend.
import ( "errors" "github.com/yshengliao/gortexa/cache")
c, err := cache.New(cfg.Cache)if err != nil { return err}defer c.Close()if err := c.Set(ctx, "k", []byte("v"), time.Minute); err != nil { return err}b, err := c.Get(ctx, "k")if errors.Is(err, cache.ErrCacheMiss) { // key absent}storage
Section titled “storage”Builds a PgBouncer-safe pgx connection pool plus a query tracer that emits OTel DB spans. It returns a *pgxpool.Pool.
import ( "go.opentelemetry.io/otel" "github.com/yshengliao/gortexa/storage")
tracer := storage.NewDBTracer(otel.GetTracerProvider())pool, err := storage.NewPool(ctx, cfg.DB, tracer) // pass nil for no spansif err != nil { return err}defer pool.Close()client
Section titled “client”Outbound client constructors with OTel instrumentation already wired in.
import "github.com/yshengliao/gortexa/client"
conn, err := client.NewGRPCConn(client.GRPCClientConfig{Target: "svc:50051", Insecure: true})if err != nil { return err}defer conn.Close()
hc := client.NewHTTPClient(client.HTTPClientConfig{Timeout: 5 * time.Second}) // zero defaults to 30sInsecure: true is for local development only; use TLS in production.
Related
Section titled “Related”- Configuration: the config keys and semantics for cache, MQ and storage
- Core: how these are assembled into the kernel
- Full example: one
main.gowiring everything together