Skip to content

coregx/pubsub

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PubSub

Production-ready Pub/Sub library and standalone service for Go

Works both as a library for embedding in your application AND as a standalone microservice with REST API.

CI Go Reference Go Report Card codecov License Release

Features

Core

  • Reliable Message Delivery — Guaranteed delivery with exponential backoff retry
  • Exponential Backoff — 30s → 1m → 2m → 4m → 8m → 16m → 30m (max)
  • Dead Letter Queue (DLQ) — Automatic handling of failed messages after 5 attempts
  • DLQ Statistics — Track failure reasons and resolution metrics
  • Domain-Driven Design — Rich domain models with business logic
  • Repository Pattern — Clean data access abstraction

Architecture

  • Pluggable — Bring your own Logger, Notification system, Delivery gateway
  • Options Pattern — Modern Go API (2026 best practices)
  • Clean Architecture — Services, Repositories, Models separation
  • Battle-Tested — Production-proven in FreiCON Railway Management System

Database Support

  • MySQL — Full support with Relica adapters
  • PostgreSQL — Full support with Relica adapters
  • SQLite — Full support with Relica adapters
  • Type-Safe Queries — Relica v0.14 expression API (no raw SQL)

Deployment Options

  • As Library — Embed in your Go application
  • As Service — Standalone PubSub server with REST API (Fursy framework)
  • Docker Ready — Production Dockerfile + docker-compose
  • Cloud Native — 12-factor app, ENV config, health checks

Installation

As Library

go get github.com/coregx/pubsub@latest

As Standalone Service

# Using Docker (recommended)
cd cmd/pubsub-server
docker-compose up -d

# Or build from source
go build ./cmd/pubsub-server

Quick Start

Option 1: Standalone Service

cd cmd/pubsub-server
docker-compose up -d

Access API at http://localhost:8080

Option 2: Embedded Library

package main

import (
    "context"
    "database/sql"
    "time"

    "github.com/coregx/pubsub"
    "github.com/coregx/pubsub/adapters/relica"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, _ := sql.Open("mysql", "user:pass@tcp(localhost:3306)/pubsub?parseTime=true")

    repos := relica.NewRepositories(db, "mysql")

    publisher, _ := pubsub.NewPublisher(
        pubsub.WithPublisherRepositories(
            repos.Message, repos.Queue, repos.Subscription, repos.Topic,
        ),
        pubsub.WithPublisherLogger(logger),
    )

    result, _ := publisher.Publish(context.Background(), pubsub.PublishRequest{
        TopicCode:  "user.signup",
        Identifier: "user-123",
        Data:       `{"userId": 123, "email": "user@example.com"}`,
    })

    worker, _ := pubsub.NewQueueWorker(
        pubsub.WithRepositories(repos.Queue, repos.Message, repos.Subscription, repos.DLQ),
        pubsub.WithDelivery(transmitterProvider, gateway),
        pubsub.WithLogger(logger),
    )

    worker.Run(context.Background(), 30*time.Second)
}

Architecture

┌─────────────────────────────────────┐
│         Your Application            │
│  (or Fursy REST API for standalone)  │
└─────────────┬───────────────────────┘
              │
┌─────────────▼───────────────────────┐
│          Services Layer             │
│  - Publisher                        │
│  - SubscriptionManager              │
│  - QueueWorker                      │
└─────────────┬───────────────────────┘
              │
┌─────────────▼───────────────────────┐
│    Relica v0.14 Adapters            │
│  Type-safe expression API           │
│  MySQL / PostgreSQL / SQLite        │
└─────────────┬───────────────────────┘
              │
┌─────────────▼───────────────────────┐
│          Database                   │
└─────────────────────────────────────┘

REST API (Standalone Service)

The standalone server uses Fursy framework with type-safe generic handlers and RFC 9457 Problem Details for error responses.

Publish Message

POST /api/v1/publish
Content-Type: application/json

{
  "topicCode": "user.signup",
  "identifier": "optional-dedup-key",
  "data": {
    "userId": 123,
    "email": "user@example.com"
  }
}

Subscribe to Topic

POST /api/v1/subscribe

{
  "subscriberID": 1,
  "topicCode": "user.signup",
  "identifier": "webhook-receiver-1"
}

List Subscriptions

GET /api/v1/subscriptions?subscriberID=1

Unsubscribe

DELETE /api/v1/subscriptions/123

Health Check

GET /api/v1/health

Configuration

Library Configuration (Go)

worker, err := pubsub.NewQueueWorker(
    pubsub.WithRepositories(queueRepo, msgRepo, subRepo, dlqRepo),
    pubsub.WithDelivery(transmitterProvider, gateway),
    pubsub.WithLogger(logger),
    pubsub.WithBatchSize(100),
    pubsub.WithRetryStrategy(customStrategy),
    pubsub.WithNotifications(notifService),
)

Service Configuration (ENV)

SERVER_HOST=0.0.0.0
SERVER_PORT=8080

DB_DRIVER=mysql          # mysql, postgres, sqlite3
DB_HOST=localhost
DB_PORT=3306
DB_USER=pubsub
DB_PASSWORD=your_password
DB_NAME=pubsub
DB_PREFIX=pubsub_

PUBSUB_BATCH_SIZE=100
PUBSUB_WORKER_INTERVAL=30
PUBSUB_ENABLE_NOTIFICATIONS=true

How It Works

Message Flow

1. PUBLISH
   Publisher → Topic → Create Message
                    → Find Active Subscriptions
                    → Create Queue Items (one per subscription)

2. WORKER (Background)
   QueueWorker → Find Pending/Retryable Items (batch)
              → Deliver to Subscribers (via webhooks/gateway)
              → On Success: Mark as SENT
              → On Failure: Retry with exponential backoff
              → After 5 failures: Move to DLQ

3. DLQ (Dead Letter Queue)
   Failed items → Manual review
               → Resolve or Delete

Retry Schedule

Attempt 1: Immediate
Attempt 2: +30 seconds
Attempt 3: +1 minute
Attempt 4: +2 minutes
Attempt 5: +4 minutes
Attempt 6: +8 minutes (moves to DLQ after this)

Testing

# Run unit tests
go test ./model/... ./retry/... . ./cmd/pubsub-server/internal/config/...

# Run with coverage
go test -cover ./model/... ./retry/... . ./cmd/pubsub-server/internal/api/...

# Integration tests (requires CGO for SQLite)
CGO_ENABLED=1 go test ./adapters/relica/...

# All tests
go test ./...

Test Coverage

Package Coverage
model/ 95.9%
retry/ 100%
pubsub (root) 82.4%
config/ 100%
api/ (handlers) 94.4%
adapters/relica/ CI only (SQLite CGO)

Docker Deployment

# Build image
docker build -t pubsub-server:0.2.0 -f cmd/pubsub-server/Dockerfile .

# Run with environment
docker run -d \
  -p 8080:8080 \
  -e DB_DRIVER=mysql \
  -e DB_HOST=mysql \
  -e DB_PASSWORD=secret \
  pubsub-server:0.2.0

Roadmap

v0.1.0 (Released)

  • Core PubSub functionality
  • Relica adapters (MySQL/PostgreSQL/SQLite)
  • Publisher + SubscriptionManager services
  • Standalone REST API server
  • Docker support

v0.2.0 (Current)

  • Relica v0.14 type-safe expression API
  • Fursy v0.4 HTTP framework with generic handlers
  • RFC 9457 Problem Details for error responses
  • Comprehensive test suite (82-100% coverage)
  • CI with MySQL/PostgreSQL service containers
  • OIDC Codecov integration
  • Delivery providers (HTTP webhooks, gRPC)
  • Message encryption
  • Rate limiting
  • Prometheus metrics

v1.0.0 (Planned)

  • API stability guarantee
  • Long-term support (3+ years)
  • OpenAPI/Swagger docs
  • Authentication/Authorization

Contributing

Contributions welcome!

  1. Fork the repository
  2. Create feature branch (git checkout -b feature/amazing)
  3. Commit changes (git commit -m 'feat: add amazing feature')
  4. Push to branch (git push origin feature/amazing)
  5. Open Pull Request

See CONTRIBUTING.md for full guidelines.

License

MIT License — see LICENSE file for details.

Dependencies

  • Relica v0.14 — Type-safe database query builder
  • Fursy v0.4 — HTTP framework (standalone server only)
  • ozzo-validation — Request validation

Support


Production-ready and battle-tested in FreiCON Railway Management System. Part of the CoreGX ecosystem.

About

Production-ready Pub/Sub library and standalone service for Go. Reliable messaging, DLQ, exponential backoff, clean architecture.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Contributors

Languages