1# Strom Integration Guide: Merging & Kafka
3Quick visual guide to merging streams and integrating with Kafka.
5## π Merging Strategies
7### 1. `merge` - Non-Deterministic (Race-Based)
10result = Strom.merge stream1 stream2
14Stream 1: [1, 2, 3] βββ
15 βββ [?, ?, ?, ?, ?, ?] (non-deterministic order)
16Stream 2: [a, b, c] βββ
19**Use for**: Event streams, multiple sources, max throughput
23### 2. `append` / `concat` - Sequential
26result = stream1 `Strom.append` stream2
28result = Strom.concat [stream1, stream2, stream3]
32Stream 1: [1, 2, 3] βββ
33 βββ [1, 2, 3, a, b, c] (deterministic)
34Stream 2: [a, b, c] βββ
38**Use for**: Pagination, stages, fallbacks
42### 3. `interleave` - Deterministic Alternating
45result = Strom.interleave stream1 stream2
49Stream 1: [1, 2, 3] βββ
50 βββ [1, a, 2, b, 3, c] (alternates)
51Stream 2: [a, b, c] βββ
54**Use for**: Fair scheduling, round-robin, load balancing
58### 4. `zip` - Pair Elements
61result = Strom.zip stream1 stream2
65Stream 1: [1, 2, 3] βββ
66 βββ [(1,a), (2,b), (3,c)]
67Stream 2: [a, b, c] βββ
70**Use for**: Joining related data, adding indices
74### 5. `race` - First Wins
77result = Strom.race [stream1, stream2, stream3]
81Stream 1: [slow...] βββ
83Stream 2: [FAST!] βββββββ [FAST!] (first to emit wins)
85Stream 3: [slower] βββββ
88**Use for**: Timeouts, fastest response, circuit breakers
92### 6. Do-Notation - Cartesian Product
102Stream 1: [1, 2] βββ
103 βββ [(1,a), (1,b), (2,a), (2,b)]
104Stream 2: [a, b] βββ (all combinations)
107**Use for**: All combinations, test cases, grids
111## π― Quick Decision Tree
114Need to merge streams?
117β ββ YES β Use `append`/`concat`
118β ββ NO β Continue...
120ββ Need all combinations?
121β ββ YES β Use do-notation
122β ββ NO β Continue...
125β ββ YES β Use `zip`
126β ββ NO β Continue...
129β ββ YES β Use `race`
130β ββ NO β Continue...
132ββ Want fair scheduling?
133β ββ YES β Use `interleave`
134β ββ NO β Use `merge`
139## β Kafka Integration Patterns
141### Pattern 1: Simple Consumer
144kafkaStream config "my-topic"
145 # Strom.mapM processMessage
146 # Strom.traverse_ handleResult
149### Pattern 2: Infinite Consumer with Batching
152kafkaInfinite config "my-topic"
153 # Strom.grouped 100 -- Batch 100
154 # Strom.traverse_ processBatch
157### Pattern 3: Consumer β Producer Pipeline
160producer <- createProducer config
162kafkaStream config "input"
163 # Strom.mapParallel 10 transform
165 # Strom.traverse_ (\batch ->
166 producer.sendBatch "output" batch
170### Pattern 4: Multi-Topic Consumer
173-- Option A: Sequential
175 [ kafkaStream config "topic1"
176 , kafkaStream config "topic2"
177 , kafkaStream config "topic3"
179 # Strom.traverse_ process
181-- Option B: With tagging
183 [ kafkaStream config "t1" # Strom.map (\m -> {topic: "t1", msg: m})
184 , kafkaStream config "t2" # Strom.map (\m -> {topic: "t2", msg: m})
186 # Strom.traverse_ routeByTopic
189### Pattern 5: Error Handling with DLQ
192producer <- createProducer config
195 # Strom.mapM (\msg ->
197 # Om.catchAll (\err -> do
198 producer.send "dlq-topic" msg
202 # Strom.collect identity
206### Pattern 6: Exactly-Once Semantics
209consumer <- createConsumer config
210producer <- createProducer config
213 batch <- consumer.consume 5000
214 processed <- Array.traverse transform batch
215 producer.sendBatch "output" processed
216 consumer.commit -- After successful send
224## π Real-World: Complete ETL Pipeline
227-- Kafka β Transform β Enrich β Validate β Kafka
228kafkaETL :: Om Context () Unit
230 producer <- createProducer producerConfig
232 kafkaInfinite consumerConfig "raw-events"
233 # Strom.mapM parseEvent -- Parse JSON
234 # Strom.collect identity -- Filter failures
235 # Strom.filter isValidEvent -- Business validation
236 # Strom.mapParallel 10 enrichWithUserData -- Parallel enrichment
237 # Strom.filter (\e -> e.user.active) -- Filter inactive
238 # Strom.grouped 100 -- Batch
239 # Strom.tapM logBatchStats -- Monitor
240 # Strom.traverse_ (\batch -> do -- Send & commit
241 producer.sendBatch "enriched-events" batch
246**With Do-Notation for Multiple Topics:**
249import Yoga.Om.Strom.Do (guard)
251multiTopicETL :: Om Context () Unit
253 producer <- createProducer config
256 -- Merge 3 topics with filtering
258 [ kafkaStream config "events-v1"
259 , kafkaStream config "events-v2"
260 , kafkaStream config "events-v3"
263 -- Parse based on topic
264 parsed <- Strom.fromOm $ parseByTopic msg
265 guard (isValid parsed)
269 enriched <- Strom.fromOm $ enrichEvent event
270 guard enriched.isComplete
274 Om.fromAff $ producer.send "output" (serialize enriched)
281## π Comparison: Merge Methods
283| Method | Order | Speed | Memory | Best For |
284|--------|-------|-------|--------|----------|
285| `merge` | β | β‘β‘β‘ | πΎ | High throughput |
286| `append` | β
| β‘ | πΎ | Stages |
287| `concat` | β
| β‘ | πΎ | Multiple stages |
288| `interleave` | β
| β‘β‘ | πΎπΎ | Fair scheduling |
289| `zip` | β
| β‘β‘ | πΎπΎ | Pairing |
290| `race` | β | β‘β‘β‘ | πΎ | Fastest wins |
291| Do-notation | β
| β‘ | πΎπΎπΎ | All combos |
2991. **5 merge strategies** - each with different semantics
3002. **Choose based on needs** - order, speed, semantics
3013. **Composable** - can combine strategies
3024. **Type-safe** - errors tracked through merges
3061. **Simple pattern** - `unfoldOm` for polling
3072. **Natural backpressure** - pull-based Strom throttles automatically
3083. **Batching** - use `grouped` for efficiency
3094. **Parallel** - use `mapParallel` for throughput
3105. **Error handling** - use `catchAll` and DLQ patterns
3116. **Exactly-once** - read β process β send β commit
315β
**Batch messages** - Group for efficiency
316β
**Use parallel processing** - `mapParallel` for I/O
317β
**Handle errors gracefully** - DLQ pattern
318β
**Commit after processing** - Exactly-once semantics
319β
**Monitor throughput** - Log batch sizes
320β
**Test with mocks** - Replace Kafka with `fromArray`
326- **[MERGING.md](./MERGING.md)** - Detailed merge strategies
327- **[KAFKA_INTEGRATION.md](./KAFKA_INTEGRATION.md)** - Complete Kafka guide
328- **[examples/MergingShowcase.purs](./examples/MergingShowcase.purs)** - All patterns
329- **[examples/KafkaIntegration.purs](./examples/KafkaIntegration.purs)** - Kafka examples
330- **[examples/KafkaIntegration.js](./examples/KafkaIntegration.js)** - FFI implementation
334**Strom makes stream merging and Kafka integration simple and type-safe!** π
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list