-
Notifications
You must be signed in to change notification settings - Fork 637
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make gossip available as a mem stream: $mem-gossip
Works very similarly to the $mem-node-state stream. Factored out a helper class.
- Loading branch information
1 parent
139fb53
commit 36fd072
Showing
8 changed files
with
328 additions
and
122 deletions.
There are no files selected for viewing
88 changes: 88 additions & 0 deletions
88
src/EventStore.Core.XUnit.Tests/Services/GossipListenerServiceTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using System; | ||
using System.Net; | ||
using System.Text; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using System.Threading.Channels; | ||
using System.Threading.Tasks; | ||
using EventStore.Core.Cluster; | ||
using EventStore.Core.Messages; | ||
using EventStore.Core.Messaging; | ||
using EventStore.Core.Services; | ||
using Xunit; | ||
|
||
namespace EventStore.Core.XUnit.Tests.Services.VNode; | ||
|
||
public class GossipListenerServiceTests { | ||
private readonly GossipListenerService _sut; | ||
private readonly ChannelReader<Message> _channelReader; | ||
private readonly Guid _nodeId = Guid.NewGuid(); | ||
|
||
private readonly JsonSerializerOptions _options = new() { | ||
Converters = { | ||
new JsonStringEnumConverter(), | ||
}, | ||
}; | ||
|
||
public GossipListenerServiceTests() { | ||
var channel = Channel.CreateUnbounded<Message>(); | ||
_channelReader = channel.Reader; | ||
var commitPosition = 0; | ||
_sut = new GossipListenerService( | ||
nodeId: _nodeId, | ||
publisher: new EnvelopePublisher(new ChannelEnvelope(channel)), | ||
getNextCommitPosition: () => ++commitPosition); | ||
} | ||
|
||
[Fact] | ||
public async Task notify_state_change() { | ||
static int random() => Random.Shared.Next(65000); | ||
|
||
var member = MemberInfo.ForVNode( | ||
instanceId: Guid.NewGuid(), | ||
timeStamp: DateTime.Now, | ||
state: Data.VNodeState.DiscoverLeader, | ||
isAlive: true, | ||
internalTcpEndPoint: default, | ||
internalSecureTcpEndPoint: new DnsEndPoint("myhost", random()), | ||
externalTcpEndPoint: default, | ||
externalSecureTcpEndPoint: new DnsEndPoint("myhost", random()), | ||
httpEndPoint: new DnsEndPoint("myhost", random()), | ||
advertiseHostToClientAs: "advertiseHostToClientAs", | ||
advertiseHttpPortToClientAs: random(), | ||
advertiseTcpPortToClientAs: random(), | ||
lastCommitPosition: random(), | ||
writerCheckpoint: random(), | ||
chaserCheckpoint: random(), | ||
epochPosition: random(), | ||
epochNumber: random(), | ||
epochId: Guid.NewGuid(), | ||
nodePriority: random(), | ||
isReadOnlyReplica: true); | ||
|
||
// when | ||
_sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo(member))); | ||
|
||
// then | ||
var @event = Assert.IsType<StorageMessage.InMemoryEventCommitted>(await _channelReader.ReadAsync()); | ||
|
||
Assert.Equal(SystemStreams.GossipStream, @event.Event.EventStreamId); | ||
Assert.Equal(GossipListenerService.EventType, @event.Event.EventType); | ||
Assert.Equal(0, @event.Event.EventNumber); | ||
|
||
var expectedBytes = JsonSerializer.SerializeToUtf8Bytes( | ||
new { | ||
NodeId = _nodeId, | ||
Members = new[] { new ClientClusterInfo.ClientMemberInfo(member) }, | ||
}, | ||
_options); | ||
|
||
var actualBytes = @event.Event.Data; | ||
|
||
Assert.Equal( | ||
Encoding.UTF8.GetString(expectedBytes), | ||
Encoding.UTF8.GetString(actualBytes.Span)); | ||
|
||
Assert.Equal(expectedBytes, actualBytes); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using EventStore.Core.Bus; | ||
using EventStore.Core.Messages; | ||
using EventStore.Core.Services.Storage; | ||
|
||
namespace EventStore.Core.Services; | ||
|
||
public class GossipListenerService : | ||
IInMemoryStreamReader, | ||
IHandle<GossipMessage.GossipUpdated> { | ||
|
||
private readonly SingleEventInMemoryStream _stream; | ||
private readonly Guid _nodeId; | ||
public const string EventType = "$GossipUpdated"; | ||
|
||
private readonly JsonSerializerOptions _options = new() { | ||
Converters = { | ||
new JsonStringEnumConverter(), | ||
}, | ||
}; | ||
|
||
public GossipListenerService(Guid nodeId, IPublisher publisher, Func<long> getNextCommitPosition) { | ||
_stream = new(publisher, getNextCommitPosition, SystemStreams.GossipStream); | ||
_nodeId = nodeId; | ||
} | ||
|
||
public void Handle(GossipMessage.GossipUpdated message) { | ||
// SystemStreams.GossipStream is a system stream so only readable by admins | ||
// we use ClientMemberInfo because plugins will consume this stream and | ||
// it is less likely to change than the internal gossip. | ||
var payload = new { | ||
NodeId = _nodeId, | ||
Members = message.ClusterInfo.Members.Select(static x => | ||
new Cluster.ClientClusterInfo.ClientMemberInfo(x)), | ||
}; | ||
|
||
var data = JsonSerializer.SerializeToUtf8Bytes(payload, _options); | ||
_stream.Write(EventType, data); | ||
} | ||
|
||
public ClientMessage.ReadStreamEventsForwardCompleted ReadForwards( | ||
ClientMessage.ReadStreamEventsForward msg) => _stream.ReadForwards(msg); | ||
|
||
public ClientMessage.ReadStreamEventsBackwardCompleted ReadBackwards( | ||
ClientMessage.ReadStreamEventsBackward msg) => _stream.ReadBackwards(msg); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.