Skip to content

Commit 7a177c1

Browse files
eabaAaronontheweb
andauthored
Docs: Updated Cluster Distributed PubSub documentation (#5566)
* Updated Cluster Distributed PubSub documentation * Fix linting unknown DeadLetter word * Fixed lint no-multiple-blank issue * Fix lint unordered list issue * Update distributed-publish-subscribe.md * Update distributed-publish-subscribe.md * Added examples for code referencing * Fixed linting * Fixed typo Co-authored-by: Aaron Stannard <[email protected]>
1 parent 7a1ce88 commit 7a177c1

File tree

15 files changed

+374
-132
lines changed

15 files changed

+374
-132
lines changed

docs/articles/clustering/distributed-publish-subscribe.md

Lines changed: 21 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -30,85 +30,25 @@ You register actors to the local mediator with `DistributedPubSubMediator.Subscr
3030

3131
You publish messages by sending `DistributedPubSubMediator.Publish` message to the local mediator.
3232

33-
Actors are automatically removed from the registry when they are terminated, or you can explicitly remove entries with `DistributedPubSubMediator.Unsubscribe`.
33+
Topic actors are automatically removed from the registry when they are terminated; they are terminated if there are no subscribers for the duration configured by `akka.cluster.pub-sub.removed-time-to-live`, which defaults to 2 minutes. You can change the deadline by setting `removed-time-to-live` to a custom duration.
34+
35+
You can `Unsubscribe` from a topic with `DistributedPubSubMediator.Unsubscribe`.
3436

3537
An example of a subscriber actor:
3638

37-
```csharp
38-
public class Subscriber : ReceiveActor
39-
{
40-
private readonly ILoggingAdapter log = Context.GetLogger();
41-
42-
public Subscriber()
43-
{
44-
var mediator = DistributedPubSub.Get(Context.System).Mediator;
45-
46-
// subscribe to the topic named "content"
47-
mediator.Tell(new Subscribe("content", Self));
48-
49-
Receive<string>(s =>
50-
{
51-
log.Info($"Got {s}");
52-
});
53-
54-
Receive<SubscribeAck>(subscribeAck =>
55-
{
56-
if (subscribeAck.Subscribe.Topic.Equals("content")
57-
&& subscribeAck.Subscribe.Ref.Equals(Self)
58-
&& subscribeAck.Subscribe.Group == null)
59-
{
60-
log.Info("subscribing");
61-
}
62-
});
63-
}
64-
}
65-
```
39+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SamplePublishSubscribe/Subscriber.cs?name=SampleSubscriber)]
6640

6741
Subscriber actors can be started on several nodes in the cluster, and all will receive messages published to the "content" topic.
6842

69-
```csharp
70-
RunOn(() =>
71-
{
72-
Sys.ActorOf(Props.Create<Subscriber>(), "subscriber1");
73-
}, _first);
74-
75-
RunOn(() =>
76-
{
77-
Sys.ActorOf(Props.Create<Subscriber>(), "subscriber2");
78-
Sys.ActorOf(Props.Create<Subscriber>(), "subscriber3");
79-
}, _second);
80-
```
43+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SamplePublishSubscribe/Program.cs?name=subscriber)]
8144

8245
A simple actor that publishes to this "content" topic:
8346

84-
```csharp
85-
public class Publisher : ReceiveActor
86-
{
87-
public Publisher()
88-
{
89-
// activate the extension
90-
var mediator = DistributedPubSub.Get(Context.System).Mediator;
91-
92-
Receive<string>(str =>
93-
{
94-
var upperCase = str.ToUpper();
95-
mediator.Tell(new Publish("content", upperCase));
96-
});
97-
}
98-
}
99-
```
47+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SamplePublisher/Publisher.cs?name=SamplePublisher)]
10048

10149
It can publish messages to the topic from anywhere in the cluster:
10250

103-
```csharp
104-
RunOn(() =>
105-
{
106-
var publisher = Sys.ActorOf(Props.Create<Publisher>(), "publisher");
107-
108-
// after a while the subscriptions are replicated
109-
publisher.Tell("hello");
110-
}, _third);
111-
```
51+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SamplePublisher/Program.cs?name=publisher)]
11252

11353
### Topic Groups
11454

@@ -135,76 +75,34 @@ Actors are automatically removed from the registry when they are terminated, or
13575

13676
An example of a destination actor:
13777

138-
```csharp
139-
public class Destination : ReceiveActor
140-
{
141-
private readonly ILoggingAdapter log = Context.GetLogger();
142-
143-
public Destination()
144-
{
145-
// activate the extension
146-
var mediator = DistributedPubSub.Get(Context.System).Mediator;
147-
148-
// register to the path
149-
mediator.Tell(new Put(Self));
150-
151-
Receive<string>(s =>
152-
{
153-
log.Info($"Got {s}");
154-
});
155-
}
156-
}
157-
```
78+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SampleDestination/Destination.cs?name=SampleDestination)]
15879

15980
Destination actors can be started on several nodes in the cluster, and all will receive messages sent to the path (without address information).
16081

161-
```csharp
162-
RunOn(() =>
163-
{
164-
Sys.ActorOf(Props.Create<Destination>(), "destination");
165-
}, _first);
166-
167-
RunOn(() =>
168-
{
169-
Sys.ActorOf(Props.Create<Destination>(), "destination");
170-
}, _second);
171-
```
82+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SampleDestination/Program.cs?name=destination)]
17283

17384
A simple actor that sends to the path:
17485

175-
```csharp
176-
public class Sender : ReceiveActor
177-
{
178-
public Sender()
179-
{
180-
// activate the extension
181-
var mediator = DistributedPubSub.Get(Context.System).Mediator;
182-
183-
Receive<string>(str =>
184-
{
185-
var upperCase = str.ToUpper();
186-
mediator.Tell(new Send(path: "/user/destination", message: upperCase, localAffinity: true));
187-
});
188-
}
189-
}
190-
```
86+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SampleSender/Sender.cs?name=samplesender)]
19187

19288
It can send messages to the path from anywhere in the cluster:
19389

194-
```csharp
195-
RunOn(() =>
196-
{
197-
var sender = Sys.ActorOf(Props.Create<Sender>(), "sender");
198-
199-
// after a while the destinations are replicated
200-
sender.Tell("hello");
201-
}, _third);
202-
```
90+
[!code-csharp[Main](../../../src/examples/Cluster/PublishSubscribe/SampleSender/Program.cs?name=sender)]
20391

20492
It is also possible to broadcast messages to the actors that have been registered with `Put`. Send `DistributedPubSubMediator.SendToAll` message to the local mediator and the wrapped message will then be delivered to all recipients with a matching path. Actors with the same path, without address information, can be registered on different nodes. On each node there can only be one such actor, since the path is unique within one local actor system.
20593

20694
Typical usage of this mode is to broadcast messages to all replicas with the same path, e.g. 3 actors on different nodes that all perform the same actions, for redundancy. You can also optionally specify a property (`AllButSelf`) deciding if the message should be sent to a matching path on the self node or not.
20795

96+
## DeadLetters From `DistributedPubSub`
97+
98+
There are three factors that determine when or if a message is published to `/system/deadletters`, namely: `send-to-dead-letters-when-no-subscribers`, zero existing subscribers, or if the topic does not exist / has been terminated.
99+
100+
* **`akka.cluster.pub-sub.send-to-dead-letters-when-no-subscribers`**: this is a `DistributedPubSub` setting that, if turned off or set to `false` (it is `on`/`true` by default), will not produce `Deadletter`s when there are no subscribers or the topic does not exist.
101+
102+
* **Zero Existing Subscribers**: A message is sent to the DeadLetter if **`Send-to-dead-letters-when-no-subscribers`** is on/true and there are no existing subscriber(s) to receive it. `Akka.Cluster.DistributedPubSub` does not support queueing up messages while there are no existing subscribers!
103+
104+
* **Terminated Topic Actor**: When there are no existing subscribers and no new subscription for a duration of, say 2 minutes (the default for `removed-time-to-live`), the Topic Actor is terminated and if **`Send-to-dead-letters-when-no-subscribers`** is on/true, messages are sent to DeadLetter.
105+
208106
## DistributedPubSub Extension
209107

210108
In the example above the mediator is started and accessed with the `Akka.Cluster.Tools.PublishSubscribe.DistributedPubSub` extension. That is convenient and perfectly fine in most cases, but it can be good to know that it is possible to start the mediator actor as an ordinary actor and you can have several different mediators at the same time to be able to divide a large number of actors/topics to different mediators. For example you might want to use different cluster roles for different mediators.

docs/cSpell.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@
104104
"mergetool",
105105
"titlecase",
106106
"Varghese",
107-
"Vertech"
107+
"Vertech",
108+
"DeadLetter"
108109
],
109110
"ignoreRegExpList": [
110111
"\\((.*)\\)", // Markdown links

src/Akka.sln

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.29911.84
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.32014.148
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmark", "Benchmark", "{73108242-625A-4D7B-AA09-63375DBAE464}"
77
EndProject
@@ -244,19 +244,29 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerializationBenchmarks", "
244244
EndProject
245245
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DDataStressTest", "examples\Cluster\DData\DDataStressTest\DDataStressTest.csproj", "{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}"
246246
EndProject
247-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Cluster.Benchmarks", "benchmark\Akka.Cluster.Benchmarks\Akka.Cluster.Benchmarks.csproj", "{3CEBB0AE-6A88-4C32-A1D3-A8FB1E7E236B}"
247+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Cluster.Benchmarks", "benchmark\Akka.Cluster.Benchmarks\Akka.Cluster.Benchmarks.csproj", "{3CEBB0AE-6A88-4C32-A1D3-A8FB1E7E236B}"
248248
EndProject
249249
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sharding", "Sharding", "{CF2704C6-3A27-450F-9C60-081341D88C1D}"
250250
EndProject
251-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShoppingCart", "examples\Cluster\ClusterSharding\ShoppingCart\ShoppingCart.csproj", "{9F8CCEDE-E871-473A-9C9A-DDDDE69E5130}"
251+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShoppingCart", "examples\Cluster\ClusterSharding\ShoppingCart\ShoppingCart.csproj", "{9F8CCEDE-E871-473A-9C9A-DDDDE69E5130}"
252252
EndProject
253253
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Persistence", "Persistence", "{A640E39E-F45C-4AE9-AABF-7F1432D357DA}"
254254
EndProject
255-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Persistence.Custom", "examples\Akka.Persistence.Custom\Akka.Persistence.Custom.csproj", "{B9091AE9-B257-4D3A-A9BC-EE2B43AF57A8}"
255+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Persistence.Custom", "examples\Akka.Persistence.Custom\Akka.Persistence.Custom.csproj", "{B9091AE9-B257-4D3A-A9BC-EE2B43AF57A8}"
256256
EndProject
257-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Persistence.Custom.Tests", "examples\Akka.Persistence.Custom.Tests\Akka.Persistence.Custom.Tests.csproj", "{F6C974B8-48F8-41C7-95AC-3CFAA720E0E4}"
257+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Persistence.Custom.Tests", "examples\Akka.Persistence.Custom.Tests\Akka.Persistence.Custom.Tests.csproj", "{F6C974B8-48F8-41C7-95AC-3CFAA720E0E4}"
258258
EndProject
259-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Cluster.Cpu.Benchmark", "benchmark\Akka.Cluster.Cpu.Benchmark\Akka.Cluster.Cpu.Benchmark.csproj", "{6FA94D22-9369-4A60-BBC1-764CA68F4ED1}"
259+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Cluster.Cpu.Benchmark", "benchmark\Akka.Cluster.Cpu.Benchmark\Akka.Cluster.Cpu.Benchmark.csproj", "{6FA94D22-9369-4A60-BBC1-764CA68F4ED1}"
260+
EndProject
261+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PublishSubscribe", "PublishSubscribe", "{51C887A7-7A69-43E2-9BE2-17016E2D8476}"
262+
EndProject
263+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleSubscriber", "examples\Cluster\PublishSubscribe\SamplePublishSubscribe\SampleSubscriber.csproj", "{F8BA242A-AEA4-46AC-BA08-C11C5624256D}"
264+
EndProject
265+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamplePublisher", "examples\Cluster\PublishSubscribe\SamplePublisher\SamplePublisher.csproj", "{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}"
266+
EndProject
267+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleDestination", "examples\Cluster\PublishSubscribe\SampleDestination\SampleDestination.csproj", "{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}"
268+
EndProject
269+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleSender", "examples\Cluster\PublishSubscribe\SampleSender\SampleSender.csproj", "{A5392607-15B8-4869-BB20-FAAD4D09E08B}"
260270
EndProject
261271
Global
262272
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1209,6 +1219,54 @@ Global
12091219
{6FA94D22-9369-4A60-BBC1-764CA68F4ED1}.Release|x64.Build.0 = Release|Any CPU
12101220
{6FA94D22-9369-4A60-BBC1-764CA68F4ED1}.Release|x86.ActiveCfg = Release|Any CPU
12111221
{6FA94D22-9369-4A60-BBC1-764CA68F4ED1}.Release|x86.Build.0 = Release|Any CPU
1222+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1223+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Debug|Any CPU.Build.0 = Debug|Any CPU
1224+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Debug|x64.ActiveCfg = Debug|Any CPU
1225+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Debug|x64.Build.0 = Debug|Any CPU
1226+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Debug|x86.ActiveCfg = Debug|Any CPU
1227+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Debug|x86.Build.0 = Debug|Any CPU
1228+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Release|Any CPU.ActiveCfg = Release|Any CPU
1229+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Release|Any CPU.Build.0 = Release|Any CPU
1230+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Release|x64.ActiveCfg = Release|Any CPU
1231+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Release|x64.Build.0 = Release|Any CPU
1232+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Release|x86.ActiveCfg = Release|Any CPU
1233+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D}.Release|x86.Build.0 = Release|Any CPU
1234+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1235+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Debug|Any CPU.Build.0 = Debug|Any CPU
1236+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Debug|x64.ActiveCfg = Debug|Any CPU
1237+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Debug|x64.Build.0 = Debug|Any CPU
1238+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Debug|x86.ActiveCfg = Debug|Any CPU
1239+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Debug|x86.Build.0 = Debug|Any CPU
1240+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Release|Any CPU.ActiveCfg = Release|Any CPU
1241+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Release|Any CPU.Build.0 = Release|Any CPU
1242+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Release|x64.ActiveCfg = Release|Any CPU
1243+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Release|x64.Build.0 = Release|Any CPU
1244+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Release|x86.ActiveCfg = Release|Any CPU
1245+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724}.Release|x86.Build.0 = Release|Any CPU
1246+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1247+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Debug|Any CPU.Build.0 = Debug|Any CPU
1248+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Debug|x64.ActiveCfg = Debug|Any CPU
1249+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Debug|x64.Build.0 = Debug|Any CPU
1250+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Debug|x86.ActiveCfg = Debug|Any CPU
1251+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Debug|x86.Build.0 = Debug|Any CPU
1252+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Release|Any CPU.ActiveCfg = Release|Any CPU
1253+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Release|Any CPU.Build.0 = Release|Any CPU
1254+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Release|x64.ActiveCfg = Release|Any CPU
1255+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Release|x64.Build.0 = Release|Any CPU
1256+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Release|x86.ActiveCfg = Release|Any CPU
1257+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320}.Release|x86.Build.0 = Release|Any CPU
1258+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1259+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Debug|Any CPU.Build.0 = Debug|Any CPU
1260+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Debug|x64.ActiveCfg = Debug|Any CPU
1261+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Debug|x64.Build.0 = Debug|Any CPU
1262+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Debug|x86.ActiveCfg = Debug|Any CPU
1263+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Debug|x86.Build.0 = Debug|Any CPU
1264+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Release|Any CPU.ActiveCfg = Release|Any CPU
1265+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Release|Any CPU.Build.0 = Release|Any CPU
1266+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Release|x64.ActiveCfg = Release|Any CPU
1267+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Release|x64.Build.0 = Release|Any CPU
1268+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Release|x86.ActiveCfg = Release|Any CPU
1269+
{A5392607-15B8-4869-BB20-FAAD4D09E08B}.Release|x86.Build.0 = Release|Any CPU
12121270
EndGlobalSection
12131271
GlobalSection(SolutionProperties) = preSolution
12141272
HideSolutionNode = FALSE
@@ -1280,6 +1338,7 @@ Global
12801338
{99CCB7CA-E1EE-4497-BF52-2200A0EC5CB1} = {76F58DC4-19F1-43EF-A6E2-EC1CC8395AC5}
12811339
{5AA81B79-34DD-4DD7-9D40-A5CA389786DF} = {73108242-625A-4D7B-AA09-63375DBAE464}
12821340
{C50E1A9E-820C-4E75-AE39-6F96A99AC4A7} = {D3AF8295-AEB5-4324-AA82-FCC0014AC310}
1341+
{3C6EB4EF-3726-432F-812E-07828876418B} = {CF2704C6-3A27-450F-9C60-081341D88C1D}
12831342
{AF50BDA2-EA1C-4694-9B0C-CB5D50024181} = {D3AF8295-AEB5-4324-AA82-FCC0014AC310}
12841343
{6389B968-FFBE-44AF-9016-687E837D555B} = {AF50BDA2-EA1C-4694-9B0C-CB5D50024181}
12851344
{91B73868-F504-45F2-B49F-9F967D692230} = {AF50BDA2-EA1C-4694-9B0C-CB5D50024181}
@@ -1317,12 +1376,16 @@ Global
13171376
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50} = {C50E1A9E-820C-4E75-AE39-6F96A99AC4A7}
13181377
{3CEBB0AE-6A88-4C32-A1D3-A8FB1E7E236B} = {73108242-625A-4D7B-AA09-63375DBAE464}
13191378
{CF2704C6-3A27-450F-9C60-081341D88C1D} = {C50E1A9E-820C-4E75-AE39-6F96A99AC4A7}
1320-
{3C6EB4EF-3726-432F-812E-07828876418B} = {CF2704C6-3A27-450F-9C60-081341D88C1D}
13211379
{9F8CCEDE-E871-473A-9C9A-DDDDE69E5130} = {CF2704C6-3A27-450F-9C60-081341D88C1D}
13221380
{A640E39E-F45C-4AE9-AABF-7F1432D357DA} = {D3AF8295-AEB5-4324-AA82-FCC0014AC310}
13231381
{B9091AE9-B257-4D3A-A9BC-EE2B43AF57A8} = {A640E39E-F45C-4AE9-AABF-7F1432D357DA}
13241382
{F6C974B8-48F8-41C7-95AC-3CFAA720E0E4} = {A640E39E-F45C-4AE9-AABF-7F1432D357DA}
13251383
{6FA94D22-9369-4A60-BBC1-764CA68F4ED1} = {73108242-625A-4D7B-AA09-63375DBAE464}
1384+
{51C887A7-7A69-43E2-9BE2-17016E2D8476} = {C50E1A9E-820C-4E75-AE39-6F96A99AC4A7}
1385+
{F8BA242A-AEA4-46AC-BA08-C11C5624256D} = {51C887A7-7A69-43E2-9BE2-17016E2D8476}
1386+
{3AF9CF2D-6C20-4CFE-BC0A-CA48F60E2724} = {51C887A7-7A69-43E2-9BE2-17016E2D8476}
1387+
{09CFD060-C7DC-49CC-A6C6-D3FE341A7320} = {51C887A7-7A69-43E2-9BE2-17016E2D8476}
1388+
{A5392607-15B8-4869-BB20-FAAD4D09E08B} = {51C887A7-7A69-43E2-9BE2-17016E2D8476}
13261389
EndGlobalSection
13271390
GlobalSection(ExtensibilityGlobals) = postSolution
13281391
SolutionGuid = {03AD8E21-7507-4E68-A4E9-F4A7E7273164}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#region SampleDestination
2+
using Akka.Actor;
3+
using Akka.Cluster.Tools.PublishSubscribe;
4+
using Akka.Event;
5+
6+
namespace SampleDestination
7+
{
8+
public sealed class Destination : ReceiveActor
9+
{
10+
private readonly ILoggingAdapter log = Context.GetLogger();
11+
12+
public Destination()
13+
{
14+
// activate the extension
15+
var mediator = DistributedPubSub.Get(Context.System).Mediator;
16+
17+
// register to the path
18+
mediator.Tell(new Put(Self));
19+
20+
Receive<string>(s =>
21+
{
22+
log.Info($"Got {s}");
23+
});
24+
}
25+
}
26+
#endregion
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#region destination
2+
// See https://aka.ms/new-console-template for more information
3+
using Akka.Actor;
4+
using Akka.Cluster.Tools.PublishSubscribe;
5+
using Akka.Configuration;
6+
using SampleDestination;
7+
var config = ConfigurationFactory.ParseString(@"
8+
akka {
9+
actor.provider = cluster
10+
extensions = [""Akka.Cluster.Tools.PublishSubscribe.DistributedPubSubExtensionProvider,Akka.Cluster.Tools""]
11+
remote {
12+
dot-netty.tcp {
13+
port = 0
14+
hostname = localhost
15+
}
16+
}
17+
cluster {
18+
seed-nodes = [""akka.tcp://cluster@localhost:5800""]
19+
}
20+
}");
21+
var actorSystem = ActorSystem.Create("cluster", config);
22+
23+
DistributedPubSub.Get(actorSystem);
24+
25+
actorSystem.ActorOf(Props.Create<Destination>(), "destination");
26+
27+
actorSystem.WhenTerminated.Wait();
28+
#endregion
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\..\..\..\contrib\cluster\Akka.Cluster.Tools\Akka.Cluster.Tools.csproj" />
12+
<ProjectReference Include="..\..\..\..\core\Akka.Cluster\Akka.Cluster.csproj" />
13+
<ProjectReference Include="..\..\..\..\core\Akka\Akka.csproj" />
14+
</ItemGroup>
15+
16+
</Project>

0 commit comments

Comments
 (0)