R-Think

Cookbook

Common patterns and recipes for building with R-Think. Each recipe solves a specific engineering problem.

Retry with Backoff

Implement retry logic with exponential backoff for transient failures.

retry.ts typescript
const resilientProtocol = Protocol.define({
  id: 'resilient-api',
  steps: [
    {
      name: 'fetch-data',
      action: fetchFromAPI,
      retry: {
        maxAttempts: 5,
        backoff: 'exponential',
        initialDelay: 1000,
        maxDelay: 30000,
        retryable: ['ECONNRESET', 'ETIMEDOUT', '503']
      }
    }
  ]
});

Composing Protocols

Compose complex workflows from smaller protocols. Each sub-protocol handles a specific concern.

compose.ts typescript
const validationProtocol = Protocol.define({ /* ... */ });
const enrichmentProtocol = Protocol.define({ /* ... */ });
const notificationProtocol = Protocol.define({ /* ... */ });

const composed = Protocol.compose({
  id: 'order-processing',
  steps: [
    { protocol: validationProtocol },
    { protocol: enrichmentProtocol },
    { protocol: notificationProtocol }
  ]
});

Composition Best Practice

Keep composed protocols idempotent. Each protocol should be able to run independently if needed.

Dynamic Rules

Generate rules dynamically based on configuration or runtime context.

dynamic-rules.ts typescript
const dynamicRules = (config) => [
  Rule.required('id'),
  Rule.type('id', 'string'),
  ...(config.requireEmail ? [Rule.matches('email', EMAIL_REGEX)] : []),
  ...(config.maxAmount ? [Rule.bounded('amount', 0, config.maxAmount)] : [])
];

const runtime = Runtime.create({
  protocol,
  rules: dynamicRules({ requireEmail: true, maxAmount: 10000 })
});