zoobzio January 11, 2026 Edit this page

Architecture

System Position

scio sits between your application logic and storage providers:

Application Layer
       │
       ▼
    ┌─────┐
    │scio │  ← URI routing, catalog, spec tracking
    └──┬──┘
       │
       ▼
┌──────────────┐
│ grub Atomic  │  ← Type-agnostic interfaces
│  Interfaces  │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│    grub      │  ← Typed wrappers
│   Wrappers   │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  Providers   │  ← Redis, PostgreSQL, S3, etc.
└──────────────┘

Data Flow

Registration

User Code                    scio                     grub
    │                          │                        │
    │  NewDatabase[User]()     │                        │
    │ ─────────────────────────┼───────────────────────▶│
    │                          │                        │
    │  .Atomic()               │                        │
    │ ─────────────────────────┼───────────────────────▶│
    │                          │   AtomicDatabase       │
    │                          │◀───────────────────────│
    │                          │                        │
    │  RegisterDatabase()      │                        │
    │ ────────────────────────▶│                        │
    │                          │  Store by URI          │
    │                          │  Track spec            │

Operations

Caller                       scio                   Provider
   │                           │                        │
   │  Get("db://users/123")    │                        │
   │ ─────────────────────────▶│                        │
   │                           │  Parse URI             │
   │                           │  Lookup provider       │
   │                           │                        │
   │                           │  Get(ctx, "123")       │
   │                           │───────────────────────▶│
   │                           │                        │
   │                           │       *atom.Atom       │
   │       *atom.Atom          │◀───────────────────────│
   │◀──────────────────────────│                        │

Thread Safety

scio uses sync.RWMutex for thread-safe access:

  • Registration operations acquire write lock
  • Read operations (Get, Exists, catalog queries) acquire read lock
  • Multiple readers can operate concurrently

Error Handling

scio uses semantic errors:

// scio-specific errors
scio.ErrInvalidURI       // URI parsing failed
scio.ErrUnknownVariant   // Unknown scheme
scio.ErrResourceNotFound // Resource not registered
scio.ErrResourceExists   // Duplicate registration
scio.ErrVariantMismatch  // Wrong operation for variant
scio.ErrKeyRequired      // Missing key in URI
scio.ErrKeyNotExpected   // Key provided but not used (Query/Select)

// Passed through from grub
scio.ErrNotFound         // Record doesn't exist
scio.ErrDuplicate        // Key already exists

Integration Patterns

Service Layer

type UserService struct {
    catalog *scio.Scio
}

func (s *UserService) GetUser(ctx context.Context, id string) (*atom.Atom, error) {
    return s.catalog.Get(ctx, "db://users/"+id)
}

Middleware

func DataContextMiddleware(s *scio.Scio) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            ctx := context.WithValue(r.Context(), "scio", s)
            next.ServeHTTP(w, r.WithContext(ctx))
        })
    }
}