Caerus LogoCaerusDocs

Shared Resource Engine (SRE)

Business Engine

El motor transaccional para reservas temporales de recursos limitados. Diseñado para cines, venta de tickets, reservas de turnos y stock de e-commerce.

Signature
const holder = await caerus.unitary(resourceKey).take(options);

Recursos Unitarios vs Pooled (Con Cupo)

En Caerus, la distinción entre un recurso del que hay exactamente uno y un recurso del que hay múltiples unidades intercambiables es una distinción formal en el sistema de tipos de los SDKs (TypeScript, Java y Go):

Recurso Unitario (unitary)

Existe exactamente una unidad en todo momento. Ejemplo: la butaca neon_D9 o el turno con un doctor a las 15:30.

unitary.tstypescript
// Toma exactamente 1 unidad
await caerus.unitary('butaca-D9').take({ ttlSeconds: 180 });
 
// caerus.unitary('...').takeMany(3); // ✗ No compila

Recurso Pooled (pooled)

Mantiene un saldo o inventario de unidades intercambiables. Ejemplo: 50 combos de pochoclos o 30 vacantes de un curso.

pooled.tstypescript
// Toma 3 unidades de las disponibles
await caerus.pooled('combo-grande').takeMany(3, { ttlSeconds: 300 });

Ciclo de Vida de una Reserva

Toda reserva devuelve un Holder que representa la retención temporal en estado PENDING:

                      ┌──────────────┐
       take()  ──────▶│   PENDING    │  (Unidades apartadas por TTL)
                      └──────┬───────┘
                             │
            confirm() ───────┼────────▶  CONFIRMED   (Venta concretada)
                             │
            release() ───────┼────────▶  RELEASED    (Liberado anticipadamente)
                             │
           TTL Expira ───────┴────────▶  EXPIRED     (Worker lo restaura solo)

Verbos Principales del SDK

1. take() / takeMany()

Aparta las unidades solicitadas. Si la plantilla exige clave de idempotencia, debes incluir idempotencyKey para garantizar que peticiones duplicadas devuelvan el mismo holder sin restar inventario doble.

take.tstypescript
const holder = await caerus.unitary('butaca_A4').take({
ttlSeconds: 120, // Expira a los 2 minutos si no se confirma
idempotencyKey: 'req_order_9981',
metadata: { cliente: 'ana@example.com' }
});

2. confirm()

Fija la reserva de manera permanente una vez recibido el pago o confirmación del usuario.

confirm.tstypescript
await caerus.confirm(holder.id);

3. release()

Cancela la retención de inmediato y devuelve el recurso a la venta sin esperar al vencimiento del TTL.

release.tstypescript
await caerus.release(holder.id);

Políticas de Conflicto: FAIL vs QUEUE

La política de conflicto se configura en la plantilla del recurso (desde el dashboard) y el motor la ejecuta automáticamente:

Estrategia FAILRechazo Directo
Si dos usuarios piden la misma butaca al mismo tiempo, el segundo recibe de inmediato un ConflictError. No hay espera.
Estrategia QUEUEFila Automática
El segundo solicitante queda encolado. Si el primer usuario libera la butaca o su tiempo expira, el motor se la asigna solo al siguiente en cuestión de segundos.
Especificación gRPC de bajo nivel

¿Construyendo un cliente en Python, C#, Rust, Ruby o cualquier otro lenguaje? Consulta los contratos proto3 completos de CreateResource, Take, Confirm y Release.

Ver Contratos Protobuf

¿Listo para probar el motor SRE?

Experimenta con reservas concurrentes en vivo directamente en el Playground interactivo o explora el código fuente y levanta el sample oficial de Caerus Cine en GitHub.