1- using FaasNet . EventMesh . Client ;
1+ using FaasNet . EventMesh . Client . Extensions ;
22using FaasNet . EventMesh . Client . Messages ;
33using FaasNet . EventMesh . Runtime . Exceptions ;
44using FaasNet . EventMesh . Runtime . Models ;
55using FaasNet . EventMesh . Runtime . Stores ;
6+ using FaasNet . RaftConsensus . Client ;
7+ using FaasNet . RaftConsensus . Core ;
8+ using FaasNet . RaftConsensus . Core . Models ;
9+ using FaasNet . RaftConsensus . Core . Stores ;
10+ using Microsoft . Extensions . Options ;
11+ using System ;
612using System . Collections . Generic ;
713using System . Diagnostics ;
14+ using System . Linq ;
815using System . Threading ;
916using System . Threading . Tasks ;
1017
@@ -13,10 +20,14 @@ namespace FaasNet.EventMesh.Runtime.Handlers
1320 public class PublishMessageRequestHandler : BaseMessageHandler , IMessageHandler
1421 {
1522 private readonly IMessageExchangeStore _messageExchangeStore ;
23+ private readonly IClusterStore _clusterStore ;
24+ private readonly ConsensusPeerOptions _peerOptions ;
1625
17- public PublishMessageRequestHandler ( IVpnStore vpnStore , IClientSessionStore clientSessionStore , IMessageExchangeStore messageExchangeStore ) : base ( clientSessionStore , vpnStore )
26+ public PublishMessageRequestHandler ( IVpnStore vpnStore , IClientSessionStore clientSessionStore , IMessageExchangeStore messageExchangeStore , IClusterStore clusterStore , IOptions < ConsensusPeerOptions > peerOption ) : base ( clientSessionStore , vpnStore )
1827 {
1928 _messageExchangeStore = messageExchangeStore ;
29+ _clusterStore = clusterStore ;
30+ _peerOptions = peerOption . Value ;
2031 }
2132
2233 public Commands Command => Commands . PUBLISH_MESSAGE_REQUEST ;
@@ -25,29 +36,10 @@ public async Task<EventMeshPackageResult> Run(Package package, CancellationToken
2536 {
2637 var publishMessageRequest = package as PublishMessageRequest ;
2738 await CheckSession ( publishMessageRequest , cancellationToken ) ;
28-
29- using ( var activity = EventMeshMeter . RequestActivitySource . StartActivity ( "Publish to local message brokers" ) )
30- {
31- if (
32- ( ! string . IsNullOrWhiteSpace ( publishMessageRequest . Urn ) && _runtimeOpts . Urn == publishMessageRequest . Urn ) ||
33- ( string . IsNullOrWhiteSpace ( publishMessageRequest . Urn ) ) )
34- {
35- foreach ( var publisher in _messagePublishers )
36- {
37- await publisher . Publish ( publishMessageRequest . CloudEvent , publishMessageRequest . Topic , sessionResult . ClientSession ) ;
38- }
39- }
40-
41- activity ? . SetStatus ( ActivityStatusCode . Ok ) ;
42- }
43-
44- using ( var activity = EventMeshMeter . RequestActivitySource . StartActivity ( "Broadcast message" ) )
45- {
46- await Broadcast ( publishMessageRequest , sessionResult . ClientSession , sessionResult . Vpn . BridgeServers ) ;
47- activity ? . SetStatus ( ActivityStatusCode . Ok ) ;
48- }
49-
50- return PackageResponseBuilder . PublishMessage ( package . Header . Seq ) ;
39+ var queueNames = await GetQueueNames ( publishMessageRequest , cancellationToken ) ;
40+ await BroadcastMessage ( publishMessageRequest , queueNames , cancellationToken ) ;
41+ var result = PackageResponseBuilder . PublishMessage ( package . Header . Seq ) ;
42+ return EventMeshPackageResult . SendResult ( result ) ;
5143 }
5244
5345 private async Task CheckSession ( PublishMessageRequest message , CancellationToken cancellationToken )
@@ -65,40 +57,47 @@ private async Task CheckSession(PublishMessageRequest message, CancellationToken
6557 }
6658 }
6759
68- private async Task BroadcastMessage ( PublishMessageRequest message , CancellationToken cancellationToken )
60+ private async Task < IEnumerable < string > > GetQueueNames ( PublishMessageRequest message , CancellationToken cancellationToken )
6961 {
70- // get all the queues from exchange.
71- // append entry | append the message to the queue.
72- // a client must pool the message from the queue (consensus).
62+ IEnumerable < MessageExchange > messageExchanges ;
63+ using ( var activity = EventMeshMeter . RequestActivitySource . StartActivity ( "Get all message exchange" ) )
64+ {
65+ messageExchanges = await _messageExchangeStore . GetAll ( cancellationToken ) ;
66+ activity ? . SetStatus ( ActivityStatusCode . Ok ) ;
67+ }
68+
69+ var queueNames = new List < string > ( ) ;
70+ foreach ( var messageExchange in messageExchanges )
71+ {
72+ if ( messageExchange . IsMatch ( message . Topic ) ) queueNames . AddRange ( messageExchange . ClientIds . Select ( ci => Models . Client . BuildQueueName ( ( ci ) ) ) ) ;
73+ }
74+
75+ return queueNames ;
7376 }
7477
75- private async Task Broadcast ( PublishMessageRequest publishMessageRequest , Models . Client client , ICollection < BridgeServer > bridgeServers )
78+ private async Task BroadcastMessage ( PublishMessageRequest message , IEnumerable < string > queueNames , CancellationToken cancellationToken )
7679 {
77- foreach ( var bridgeServer in bridgeServers )
80+ var rndClusterNode = await GetRandomClusterNode ( cancellationToken ) ;
81+ var base64Message = message . CloudEvent . SerializeBase64 ( ) ;
82+ using ( var activity = EventMeshMeter . RequestActivitySource . StartActivity ( "Broadcast message" ) )
7883 {
79- await Broadcast ( publishMessageRequest , bridgeServer , client ) ;
84+ using ( var consensusClient = new ConsensusClient ( rndClusterNode . Url , rndClusterNode . Port ) )
85+ {
86+ foreach ( var queueName in queueNames )
87+ {
88+ await consensusClient . AppendEntry ( queueName , base64Message , cancellationToken ) ;
89+ }
90+ }
8091 }
8192 }
8293
83- private async Task Broadcast ( PublishMessageRequest publishMessageRequest , BridgeServer bridgeServer , Models . Client client )
94+ private async Task < ClusterNode > GetRandomClusterNode ( CancellationToken cancellationToken )
8495 {
85- var activeSession = client . GetActiveSession ( publishMessageRequest . SessionId ) ;
86- var pid = Process . GetCurrentProcess ( ) . Id ;
87- var runtimeClient = new RuntimeClient ( bridgeServer . TargetUrn , bridgeServer . TargetPort ) ;
88- var helloResponse = await runtimeClient . Hello ( new UserAgent
89- {
90- ClientId = client . ClientId ,
91- Purpose = activeSession . Purpose ,
92- Environment = activeSession . Environment ,
93- BufferCloudEvents = activeSession . BufferCloudEvents ,
94- Urn = _runtimeOpts . Urn ,
95- Port = _runtimeOpts . Port ,
96- Pid = pid ,
97- IsServer = true ,
98- Vpn = bridgeServer . TargetVpn
99- } ) ;
100- await runtimeClient . PublishMessage ( client . ClientId , helloResponse . SessionId , publishMessageRequest . Topic , publishMessageRequest . CloudEvent , publishMessageRequest . Urn , publishMessageRequest . Port ) ;
101- await runtimeClient . Disconnect ( client . ClientId , helloResponse . SessionId ) ;
96+ var nodes = await _clusterStore . GetAllNodes ( cancellationToken ) ;
97+ nodes = nodes . Where ( n => n . Port != _peerOptions . Port || n . Url != _peerOptions . Url ) ;
98+ var rnd = new Random ( ) ;
99+ var rndIndex = rnd . Next ( 0 , nodes . Count ( ) - 1 ) ;
100+ return nodes . ElementAt ( rndIndex ) ;
102101 }
103102 }
104103}
0 commit comments