CloudMesh.DataBlocks
2.0.101
dotnet add package CloudMesh.DataBlocks --version 2.0.101
NuGet\Install-Package CloudMesh.DataBlocks -Version 2.0.101
<PackageReference Include="CloudMesh.DataBlocks" Version="2.0.101" />
<PackageVersion Include="CloudMesh.DataBlocks" Version="2.0.101" />
<PackageReference Include="CloudMesh.DataBlocks" />
paket add CloudMesh.DataBlocks --version 2.0.101
#r "nuget: CloudMesh.DataBlocks, 2.0.101"
#:package CloudMesh.DataBlocks@2.0.101
#addin nuget:?package=CloudMesh.DataBlocks&version=2.0.101
#tool nuget:?package=CloudMesh.DataBlocks&version=2.0.101
CloudMesh.DataBlocks
A lightweight, in-process actor / pipeline library built on System.Threading.Channels. Think of it as an
actor framework that went on a diet: message-driven components you wire into high-throughput processing pipelines
— fan-out, fan-in, batching, aggregation, round-robin — without pulling in a full actor runtime.
- Targets: .NET 8, 9, 10 — License: MIT
dotnet add package CloudMesh.DataBlocks
The model
A DataBlock is a component with a mailbox. It processes one message at a time (so handler state needs no
locking), receiving typed messages via ReceiveAsync<T>(...) and being fed via SubmitAsync(...). Blocks are
composed into pipelines where each stage hands work to the next.
using CloudMesh.DataBlocks;
public sealed class OrderProcessor : DataBlock
{
public OrderProcessor()
{
ReceiveAsync<Order>(async order =>
{
await ProcessAsync(order);
});
}
}
var processor = /* create/host the block */;
await processor.SubmitAsync(new Order(...), sender: null); // one message at a time, in order
The blocks
| Block | Role |
|---|---|
DataBlock |
Base consumer — decouples receiving from consuming. |
AggregationDataBlock<T> |
Fan-in: compute state over time and emit it periodically (sum/avg/frequency every N seconds). |
BufferBlock<T> |
Fan-in: batch up to N items or T milliseconds, whichever first, then consume the batch. |
BufferRouter<T> |
Fan-in: a BufferBlock<T> that forwards each batch to another block. |
RoundRobinDataBlock |
Fan-out: distribute messages fairly across child blocks, one at a time. |
SpillOverDataBlock |
Fan-out: fill each child to capacity before advancing to the next. |
DataBlockScheduler |
Schedule delayed/cancelable message delivery — timeouts, wait patterns. |
CaptureBlock |
Collect received messages into a list — mostly for unit-testing pipelines. |
BackpressureMonitor |
A hook to detect backpressure buildup in a pipeline. |
Fluent pipeline (Data Streams)
On top of the blocks sits a composable, Rx/LINQ-style pipeline builder. You pick a source, chain operators,
choose a sink with To(...), then Build() a running IPipeline<T>. Each operator is just a DataBlock that
awaits its downstream submit, so backpressure propagates upstream through the whole chain, and disposing the
pipeline drains and flushes every stage in order (buffered/aggregated items included).
using CloudMesh.DataBlocks;
await using var pipeline = Pipeline.OnManualPush<string>()
.Map(s => s.Trim().ToLowerInvariant()) // transform
.Where(s => s.Length > 0) // filter
.MapAsync(async (s, ct) => await EnrichAsync(s, ct),
degreeOfParallelism: 4) // fan-out + implicit fan-in (order NOT preserved)
.Distinct() // Rx-style operator
.Buffer(maxItems: 100, maxWaitTime: TimeSpan.FromSeconds(1)) // batch into T[]
.Reduce(batch => batch.Length) // collapse a batch to one value
.OnError((ex, item) => log.LogWarning(ex, "dropped {Item}", item)) // resilient error handler
.To(Console.WriteLine) // sink
.Build();
foreach (var word in words)
await pipeline.PushAsync(word);
// leaving the scope disposes → drains every stage
Sources
| Source | Pumps |
|---|---|
Pipeline.OnManualPush<T>() |
You feed it: await pipeline.PushAsync(item). |
Pipeline.From(IAsyncEnumerable<T>) |
Self-pumps the sequence once built. |
Pipeline.From(ChannelReader<T>) |
Self-pumps a System.Threading.Channels reader until it completes. |
Operators
| Operator | What it does |
|---|---|
Map / MapAsync(dop) |
Transform each item. dop > 1 fans out across N workers (order not preserved). |
Where |
Filter. |
Tap |
Run a side effect, pass the item through unchanged. |
Skip(n) / Take(n) |
Drop / forward the first n items (arrival order). |
Distinct() / Distinct(comparer) |
Forward only items not seen before. |
DistinctUntilChanged() / …(comparer) |
Drop consecutive duplicates. |
SelectMany(selector) |
Flatten: emit 0..n downstream items per input. |
Scan(seed, acc) |
Running fold — emit the accumulator after every item. |
Buffer(count, time) |
Batch into T[] by size or time window (fan-in). |
Reduce / ReduceAsync |
Collapse a batch (T[]) to a single value. |
Aggregate(seed, acc, window) |
Time-windowed fold — emit one value per window (fan-in). |
The stateful operators (
Skip,Take,DistinctUntilChanged,Scan) observe items in arrival order. After aMapAsync(dop > 1)fan-out that is not the source order, so place them before the fan-out if you need source order.
Sinks
To(Action<T>), To(Func<T, CancellationToken, ValueTask>), To(ICanSubmit) (an existing block; not owned/disposed),
or To(ChannelWriter<T>) (writes each item and completes the writer when the pipeline drains, so a downstream
reader.ReadAllAsync() loop terminates).
Error model
Two ways to observe failures in user code (a selector/predicate/action/fold):
OnError(Action<Exception, object?>)— a resilient handler. When any stage throws, the offending item is dropped, the handler is invoked with aPipelineExceptionand that item, and the pipeline keeps running.Completionstill finishes successfully.IPipeline<T>.Completion— aTaskthat completes when the pipeline drains normally, or faults with the firstPipelineExceptionwhen noOnErrorhandler was registered.await pipeline.Completionto observe it.
await using var pipeline = Pipeline.From(source).Map(Risky).To(Sink).Build();
try { await pipeline.Completion; } // faults on the first stage error (no OnError registered)
catch (PipelineException ex) { /* ex.Item is the offending value */ }
DisposeAsync always drains cleanly and never re-throws pipeline faults — errors are observed via OnError or
Completion. For a From/channel source, Completion also completes on its own once the source is exhausted and
the stages have drained, so you can await pipeline.Completion without disposing.
Samples
Runnable examples live in samples/DataBlocks:
ProducerConsumerSample, RoundRobinSample, AggregationSample, CaptureBlockSample, TimeoutSample,
PrioritizedConsumer, PipelineSample — a composite order-processing pipeline that wires fan-out,
content routing, buffering, and fan-in aggregation together to show how the blocks compose — and
DataStreamsSample, an end-to-end tour of the fluent pipeline API (operators, channel source/sink, error model).
When to reach for it
- Building background workers or streaming pipelines that need high throughput in-process.
- You want ordered, single-threaded-per-block processing without manual locking.
- You need batching (
BufferBlock), time-windowed aggregation (AggregationDataBlock), or load distribution (RoundRobinDataBlock/SpillOverDataBlock) as ready-made building blocks.
If you need cross-process or cross-machine messaging, this isn't that — it's deliberately in-process only.
MIT © Jessie Wadman. Part of CloudMesh.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CloudMesh.Core (>= 2.0.101)
- CloudMesh.Variant (>= 2.0.101)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
-
net8.0
- CloudMesh.Core (>= 2.0.101)
- CloudMesh.Variant (>= 2.0.101)
- Microsoft.Extensions.ObjectPool (>= 8.0.0)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
-
net9.0
- CloudMesh.Core (>= 2.0.101)
- CloudMesh.Variant (>= 2.0.101)
- Microsoft.Extensions.ObjectPool (>= 9.0.0)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.101 | 143 | 8/29/2026 |
| 2.0.100 | 789 | 8/3/2026 |
| 2.0.99 | 134 | 7/14/2026 |
| 2.0.98 | 123 | 7/14/2026 |
| 2.0.97 | 533 | 7/14/2026 |
| 2.0.96 | 129 | 6/28/2026 |
| 2.0.95 | 116 | 6/28/2026 |
| 2.0.94 | 122 | 6/28/2026 |
| 2.0.93 | 156 | 6/27/2026 |
| 2.0.92 | 135 | 6/23/2026 |
| 2.0.89 | 351 | 12/18/2025 |
| 2.0.87-preview | 241 | 8/11/2025 |
| 2.0.85-preview | 2,405 | 1/29/2025 |
| 2.0.76-preview | 202 | 1/15/2025 |
| 2.0.75-preview | 159 | 1/15/2025 |
| 2.0.74-preview | 175 | 1/15/2025 |
| 2.0.73-preview | 179 | 1/13/2025 |
| 1.0.67 | 302 | 10/28/2024 |
| 1.0.66 | 276 | 10/22/2024 |
| 1.0.65 | 266 | 10/22/2024 |