Skip to content

Commit d0815c7

Browse files
CopilotIEvangelist
andauthored
Clarify Orleans Broadcast Channels documentation with missing context and comparisons (#49373)
* Initial plan * Clarify broadcast channels documentation with missing context Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com>
1 parent 168c201 commit d0815c7

1 file changed

Lines changed: 63 additions & 9 deletions

File tree

docs/orleans/streaming/broadcast-channel.md

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
title: Broadcast channels
33
description: Learn how to work with Orleans broadcast channels.
44
ms.date: 07/03/2024
5+
ai-usage: ai-assisted
56
---
67

78
# Broadcast channels in Orleans
@@ -30,36 +31,89 @@ The broadcast channel decouples the producer and consumer of the stock price upd
3031

3132
## Define a consumer grain
3233

33-
To consume broadcast channel messages, your grain needs to implement the <xref:Orleans.BroadcastChannel.IOnBroadcastChannelSubscribed> interface. Your implementation will use the <xref:Orleans.BroadcastChannel.IBroadcastChannelSubscription.Attach%2A?displayProperty=nameWithType> method to attach to the broadcast channel. The `Attach` method takes a generic-type parameter for the message type you're going to receive. The following example shows a grain that subscribes to a broadcast channel of type `Stock`:
34+
To consume broadcast channel messages, your grain needs to implement the <xref:Orleans.BroadcastChannel.IOnBroadcastChannelSubscribed> interface. This interface enables implicit subscriptions, meaning grains are automatically subscribed to the broadcast channel when they're activated. Your implementation uses the <xref:Orleans.BroadcastChannel.IBroadcastChannelSubscription.Attach%2A?displayProperty=nameWithType> method to attach to the broadcast channel. The `Attach` method takes a generic-type parameter for the message type you're going to receive.
35+
36+
First, define the grain interface that consumers use to interact with the grain:
37+
38+
:::code source="./snippets/broadcastchannel/BroadcastChannel.GrainInterfaces/ILiveStockGrain.cs":::
39+
40+
The `ILiveStockGrain` interface uses `IGrainWithGuidKey`, which means the grain is identified by a GUID key. Next, implement the grain that subscribes to the broadcast channel:
3441

3542
:::code source="./snippets/broadcastchannel/BroadcastChannel.Silo/LiveStockGrain.cs":::
3643

3744
In the preceding code:
3845

3946
- The `LiveStockGrain` grain implements the `IOnBroadcastChannelSubscribed` interface.
40-
- The `OnSubscribed` method is called when the grain subscribes to the broadcast channel.
47+
- The `[ImplicitChannelSubscription]` attribute marks this grain for automatic subscription to broadcast channels.
48+
- The `OnSubscribed` method is called automatically when the grain is activated (when it's first used or after recovery from a failure).
4149
- The `subscription` parameter is used to call the `Attach` method to attach to the broadcast channel.
4250
- The `OnStockUpdated` method is passed to `Attach` as a callback that fires when the `Stock` message is received.
4351
- The `OnError` method is passed to `Attach` as a callback that fires when an error occurs.
4452

45-
This example grain will contain the latest stock prices as published on the broadcast channel. Any client that asks this grain for the latest stock price will get the latest price from the broadcast channel.
53+
This example grain contains the latest stock prices as published on the broadcast channel. Any client that asks this grain for the latest stock price gets the latest price from the broadcast channel.
4654

4755
## Publish messages to a broadcast channel
4856

49-
To publish messages to the broadcast channel, you need to get a reference to the broadcast channel. To do this, you need to get the <xref:Orleans.BroadcastChannel.IBroadcastChannelProvider> from the <xref:Orleans.IClusterClient>. With the provider, you can call the <xref:Orleans.BroadcastChannel.IBroadcastChannelProvider.GetChannelWriter%2A?displayProperty=nameWithType> method to get an instance of <xref:Orleans.BroadcastChannel.IBroadcastChannelWriter%601>. The writer is used to publish messages to the broadcast channel. The following example shows how to publish messages to the broadcast channel:
57+
To publish messages to the broadcast channel, you need to get a reference to the broadcast channel. To do this, get the <xref:Orleans.BroadcastChannel.IBroadcastChannelProvider> from the <xref:Orleans.IClusterClient>. With the provider, call the <xref:Orleans.BroadcastChannel.IBroadcastChannelProvider.GetChannelWriter%2A?displayProperty=nameWithType> method to get an instance of <xref:Orleans.BroadcastChannel.IBroadcastChannelWriter%601>. The writer is used to publish messages to the broadcast channel.
58+
59+
First, define a constant for the channel name to ensure the producer and consumers use the same channel identifier:
60+
61+
:::code source="./snippets/broadcastchannel/BroadcastChannel.GrainInterfaces/ChannelNames.cs":::
62+
63+
Then, create a publisher that sends messages to the broadcast channel:
5064

5165
:::code source="./snippets/broadcastchannel/BroadcastChannel.Silo/Services/StockWorker.cs":::
5266

5367
In the preceding code:
5468

5569
- The `StockWorker` class is a background service that publishes messages to the broadcast channel.
56-
- The constructor takes an `IStockClient` and <xref:Orleans.IClusterClient> as parameters.
57-
- From the cluster client instance, the <xref:Orleans.Hosting.ChannelHostingExtensions.GetBroadcastChannelProvider%2A> method is used to get the broadcast channel provider.
58-
- Using the `IStockClient`, the `StockWorker` class gets the latest stock price for a stock symbol.
59-
- Every 15 seconds, the `StockWorker` class publishes a `Stock` message to the broadcast channel.
70+
- The constructor takes a `StockClient` and <xref:Orleans.IClusterClient> as parameters.
71+
- From the cluster client instance, the <xref:Orleans.Hosting.ChannelHostingExtensions.GetBroadcastChannelProvider%2A> method is used to get the broadcast channel provider for the `LiveStockTicker` channel.
72+
- The `ChannelId.Create` method creates a channel identifier using:
73+
- The channel name (`ChannelNames.LiveStockTicker`)—this must match the name used when configuring the broadcast channel in the silo setup.
74+
- `Guid.Empty` as the namespace—for broadcast channels, all subscribers receive all messages, so the namespace is typically set to `Guid.Empty` to indicate a single shared broadcast.
75+
- Using the `StockClient`, the `StockWorker` class gets the latest stock price for each stock symbol.
76+
- Every 15 seconds, the `StockWorker` class publishes `Stock` messages to the broadcast channel.
77+
78+
The publishing of messages to a broadcast channel is decoupled from the consumer grain. The producer doesn't know about specific consumer grains. Instead, it publishes to the broadcast channel, and all implicitly subscribed grains automatically receive the messages.
79+
80+
## Broadcast channels vs. streams
81+
82+
Broadcast channels and Orleans streams (including in-memory streams) are both messaging mechanisms, but they serve different purposes and have different characteristics. The following table compares the key differences:
83+
84+
| Feature | Broadcast channels | Orleans streams |
85+
|---------|-------------------|-----------------|
86+
| **Subscription model** | Implicit—grains are automatically subscribed when activated | Explicit—grains must explicitly subscribe to streams |
87+
| **Message persistence** | Not persistent—messages are lost if no subscribers are active | Can be persistent (Azure Queues, Event Hubs) or transient (in-memory) |
88+
| **Message delivery** | Best-effort, fire-and-forget delivery | Depends on provider—can support at-least-once or exactly-once delivery |
89+
| **Use case** | Broadcasting the same message to all interested grains in real-time | Point-to-point or pub-sub messaging with delivery guarantees |
90+
| **Message history** | No message history—only current broadcasts | Streams can support rewindable subscriptions with message history |
91+
| **Scalability** | Optimized for fan-out to many consumers | Optimized for queue-based processing with backpressure |
92+
| **Consumer lifecycle** | Consumers are implicitly managed by Orleans | Consumers must manage subscription lifecycle |
93+
| **Configuration** | Simple—requires only channel name | More complex—requires stream provider configuration |
94+
95+
### When to use broadcast channels
96+
97+
Use broadcast channels when:
98+
99+
- You need to send the same message to all instances of a grain type.
100+
- Message delivery isn't critical (occasional losses are acceptable).
101+
- You want implicit subscription without managing subscription lifecycle.
102+
- You need real-time updates without message history.
103+
- You want simple configuration and setup.
104+
105+
### When to use streams
106+
107+
Use streams when:
60108

61-
The publishing of messages to a broadcast channel is decoupled from the consumer grain. The consumer grain subscribes to the broadcast channel and receives messages from the broadcast channel. The producer lives in a silo and is responsible for publishing messages to the broadcast channel and doesn't know anything about consuming grains.
109+
- You need guaranteed message delivery.
110+
- You need message persistence and replay capabilities.
111+
- You want explicit control over subscription lifecycle.
112+
- You need backpressure and flow control mechanisms.
113+
- Your messaging pattern is point-to-point or requires more complex routing.
114+
- You're integrating with external queuing systems (Event Hubs, Service Bus, Kafka).
62115

63116
## See also
64117

65118
- [Streaming with Orleans](index.md)
119+
- [Orleans stream providers](stream-providers.md)

0 commit comments

Comments
 (0)