|
1 | 1 | ---
|
2 | 2 | title: What's new in Orleans
|
3 | 3 | description: Learn about the various new features introduced in Orleans 7.0.
|
4 |
| -ms.date: 10/26/2022 |
| 4 | +ms.date: 10/31/2022 |
5 | 5 | ---
|
6 | 6 |
|
7 | 7 | # What's new in Orleans 7.0
|
@@ -399,10 +399,69 @@ In Orleans 7.0, streams are now identified using strings. The `StreamId` namespa
|
399 | 399 |
|
400 | 400 | ### Replacement of SimpleMessageStreams with BroadcastChannel
|
401 | 401 |
|
402 |
| -- If implicit subscriptions are sufficient, BroadcastChannel is a behaviorally identical replacement for _SMS_ streams. |
403 |
| -- If you need explicit subscriptions, migrate to _In-memory Streams_ |
| 402 | +`SimpleMessageStreams` (also called SMS) was removed in 7.0. SMS had the same interface as `PersistentStreams`, but its behavior was very different, since it relied on direct grain-to-grain calls. To avoid confusion, SMS was removed, and a new replacement called `BroadcastChannel` was introduced. |
404 | 403 |
|
405 |
| -<!-- TODO: add examples --> |
| 404 | +`BroadcastChannel` only supports implicit subscription and can be a direct replacement in this case. If you need explicit subscriptions or need to use the `PersistentStream` interface (for example you were using SMS in tests while using `EventHub` in production), then `MemoryStream` is the best candidate for you. |
| 405 | + |
| 406 | +`BroadcastChannel` will have the same behaviors as SMS, while `MemoryStream` will behave like other stream providers. Consider the following Broadcast Channel usage example: |
| 407 | + |
| 408 | +```csharp |
| 409 | +// Configuration |
| 410 | +builder.AddBroadcastChannel( |
| 411 | + "my-provider", |
| 412 | + options => options.FireAndForgetDelivery = false); |
| 413 | + |
| 414 | +// Publishing |
| 415 | +var grainKey = Guid.NewGuid().ToString("N"); |
| 416 | +var channelId = ChannelId.Create("some-namespace", grainKey); |
| 417 | +var stream = provider.GetChannelWriter<int>(channelId); |
| 418 | + |
| 419 | +await stream.Publish(1); |
| 420 | +await stream.Publish(2); |
| 421 | +await stream.Publish(3); |
| 422 | + |
| 423 | +// Simple implicit subscriber example |
| 424 | +[ImplicitChannelSubscription] |
| 425 | +public sealed class SimpleSubscriberGrain : Grain, ISubscriberGrain, IOnBroadcastChannelSubscribed |
| 426 | +{ |
| 427 | + // Called when a subscription is added to the grain |
| 428 | + public Task OnSubscribed(IBroadcastChannelSubscription streamSubscription) |
| 429 | + { |
| 430 | + streamSubscription.Attach<int>( |
| 431 | + item => OnPublished(streamSubscription.ChannelId, item), |
| 432 | + ex => OnError(streamSubscription.ChannelId, ex)); |
| 433 | + |
| 434 | + return Task.CompletedTask; |
| 435 | + |
| 436 | + // Called when an item is published to the channel |
| 437 | + static Task OnPublished(ChannelId id, int item) |
| 438 | + { |
| 439 | + // Do something |
| 440 | + return Task.CompletedTask; |
| 441 | + } |
| 442 | + |
| 443 | + // Called when an error occurs |
| 444 | + static Task OnError(ChannelId id, Exception ex) |
| 445 | + { |
| 446 | + // Do something |
| 447 | + return Task.CompletedTask; |
| 448 | + } |
| 449 | + } |
| 450 | +} |
| 451 | +``` |
| 452 | + |
| 453 | +Migration to `MemoryStream` will be easier, since only the configuration needs to change. Consider the following `MemoryStream` configuration: |
| 454 | + |
| 455 | +```csharp |
| 456 | +builder.AddMemoryStreams<DefaultMemoryMessageBodySerializer>( |
| 457 | + "in-mem-provider", |
| 458 | + bldr => |
| 459 | + { |
| 460 | + // Number of pulling agent to start. |
| 461 | + // DO NOT CHANGE this value once deployed, if you do rolling deployment |
| 462 | + bldr.ConfigurePartitioning(partitionCount: 8); |
| 463 | + }); |
| 464 | +``` |
406 | 465 |
|
407 | 466 | ### Open Telemetry
|
408 | 467 |
|
|
0 commit comments