# Send Dual Stream Architecture to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "dual-stream-architecture",
    "name": "Dual Stream Architecture",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/wpank/dual-stream-architecture",
    "canonicalUrl": "https://clawhub.ai/wpank/dual-stream-architecture",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/dual-stream-architecture",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=dual-stream-architecture",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/dual-stream-architecture"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/dual-stream-architecture",
    "downloadUrl": "https://openagent3.xyz/downloads/dual-stream-architecture",
    "agentUrl": "https://openagent3.xyz/skills/dual-stream-architecture/agent",
    "manifestUrl": "https://openagent3.xyz/skills/dual-stream-architecture/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/dual-stream-architecture/agent.md"
  }
}
```
## Documentation

### Dual-Stream Architecture

Publish events to Kafka (durability) and Redis Pub/Sub (real-time) simultaneously for systems needing both guaranteed delivery and instant updates.

### OpenClaw / Moltbot / Clawbot

npx clawhub@latest install dual-stream-architecture

### When to Use

Event-driven systems needing both durability AND real-time
WebSocket/SSE backends that push live updates
Dashboards showing events as they happen
Kafka consumers have lag but users expect instant updates

### Core Pattern

type DualPublisher struct {
    kafka  *kafka.Writer
    redis  *redis.Client
    logger *slog.Logger
}

func (p *DualPublisher) Publish(ctx context.Context, event Event) error {
    // 1. Kafka: Critical path - must succeed
    payload, _ := json.Marshal(event)
    err := p.kafka.WriteMessages(ctx, kafka.Message{
        Key:   []byte(event.SourceID),
        Value: payload,
    })
    if err != nil {
        return fmt.Errorf("kafka publish failed: %w", err)
    }

    // 2. Redis: Best-effort - don't fail the operation
    p.publishToRedis(ctx, event)

    return nil
}

func (p *DualPublisher) publishToRedis(ctx context.Context, event Event) {
    // Lightweight payload (full event in Kafka)
    notification := map[string]interface{}{
        "id":        event.ID,
        "type":      event.Type,
        "source_id": event.SourceID,
    }

    payload, _ := json.Marshal(notification)
    channel := fmt.Sprintf("events:%s:%s", event.SourceType, event.SourceID)

    // Fire and forget - log errors but don't propagate
    if err := p.redis.Publish(ctx, channel, payload).Err(); err != nil {
        p.logger.Warn("redis publish failed", "error", err)
    }
}

### Architecture

┌──────────────┐     ┌─────────────────┐     ┌──────────────┐
│   Ingester   │────▶│  DualPublisher  │────▶│    Kafka     │──▶ Event Processor
│              │     │                 │     │  (durable)   │
└──────────────┘     │                 │     └──────────────┘
                     │                 │     ┌──────────────┐
                     │                 │────▶│ Redis PubSub │──▶ WebSocket Gateway
                     │                 │     │ (real-time)  │
                     └─────────────────┘     └──────────────┘

### Channel Naming Convention

events:{source_type}:{source_id}

Examples:
- events:user:octocat      - Events for user octocat
- events:repo:owner/repo   - Events for a repository
- events:org:microsoft     - Events for an organization

### Batch Publishing

For high throughput:

func (p *DualPublisher) PublishBatch(ctx context.Context, events []Event) error {
    // 1. Batch to Kafka
    messages := make([]kafka.Message, len(events))
    for i, event := range events {
        payload, _ := json.Marshal(event)
        messages[i] = kafka.Message{
            Key:   []byte(event.SourceID),
            Value: payload,
        }
    }

    if err := p.kafka.WriteMessages(ctx, messages...); err != nil {
        return fmt.Errorf("kafka batch failed: %w", err)
    }

    // 2. Redis: Pipeline for efficiency
    pipe := p.redis.Pipeline()
    for _, event := range events {
        channel := fmt.Sprintf("events:%s:%s", event.SourceType, event.SourceID)
        notification, _ := json.Marshal(map[string]interface{}{
            "id":   event.ID,
            "type": event.Type,
        })
        pipe.Publish(ctx, channel, notification)
    }
    
    if _, err := pipe.Exec(ctx); err != nil {
        p.logger.Warn("redis batch failed", "error", err)
    }

    return nil
}

### Decision Tree

RequirementStreamWhyMust not lose eventKafka onlyAck required, replicatedUser sees immediatelyRedis onlySub-ms deliveryBoth durability + real-timeDual streamThis patternHigh volume (>10k/sec)Kafka, batch RedisRedis can bottleneckMany subscribers per channelRedis + local fan-outDon't hammer Redis

### Related Skills

Meta-skill: ai/skills/meta/realtime-dashboard/ — Complete realtime dashboard guide
websocket-hub-patterns — WebSocket gateway
backend/service-layer-architecture — Service integration

### NEVER Do

NEVER fail on Redis errors — Redis is best-effort. Log and continue.
NEVER send full payload to Redis — Send IDs only, clients fetch from API.
NEVER create one Redis channel per event — Use source-level channels.
NEVER skip Kafka for "unimportant" events — All events go to Kafka for replay.
NEVER use Redis Pub/Sub for persistence — Messages are fire-and-forget.

### Edge Cases

CaseSolutionRedis downLog warning, continue with Kafka onlyClient connects mid-streamQuery API for recent events, then subscribeHigh channel cardinalityUse wildcard patterns or aggregate channelsKafka backpressureBuffer in memory with timeout, fail if fullNeed event replayConsume from Kafka from offset, not Redis
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: wpank
- Version: 1.0.0
## Source health
- Status: healthy
- Source download looks usable.
- Yavira can redirect you to the upstream package for this source.
- Health scope: source
- Reason: direct_download_ok
- Checked at: 2026-04-23T16:43:11.935Z
- Expires at: 2026-04-30T16:43:11.935Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/dual-stream-architecture)
- [Send to Agent page](https://openagent3.xyz/skills/dual-stream-architecture/agent)
- [JSON manifest](https://openagent3.xyz/skills/dual-stream-architecture/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/dual-stream-architecture/agent.md)
- [Download page](https://openagent3.xyz/downloads/dual-stream-architecture)