There seem to be no docs regarding how to set up, run, and connect to an Embedded EventStore client using the EventStore.Client.Embedded nuget package. With the following code:
ClusterVNode node = EmbeddedVNodeBuilder
.AsSingleNode()
.RunInMemory()
.OnDefaultEndpoints()
.Build();
var connection = EmbeddedEventStoreConnection.Create(node);
await connection.ConnectAsync();
var sampleEventData = new EventData(Guid.NewGuid(), "myTestEvent", false, new byte[] { 6, 10, 15 }, null);
WriteResult writeResult = await connection.AppendToStreamAsync("sampleStream, ExpectedVersion.NoStream, sampleEventData);
Everything seems to work fine up until the AppendToStreamAsync
line, which throws the following exception:
Expected response of EventStore.Core.Messages.ClientMessage+WriteEventsCompleted, received EventStore.Core.Messages.ClientMessage+NotHandled instead.
What part of the magic incantation is missing to get around this exception?
Two things are missing here. First, when using the embedded eventstore client, you have to start the node:
node.Start();
Second, you have to wait for the node to become master before you can use the connection. The ClusterVNode
has an event named NodeStatusChanged
that you can listen to and find out when there is a master node. The following should work:
ClusterVNode node = EmbeddedVNodeBuilder
.AsSingleNode()
.RunInMemory()
.OnDefaultEndpoints()
.Build();
bool isNodeMaster = false;
node.NodeStatusChanged += (sender, args) => {
isNodeMaster = args.NewVNodeState == VNodeState.Master;
};
node.Start();
var stopwatch = new Stopwatch();
stopwatch.Start();
while (!isNodeMaster) {
if (stopwatch.Elapsed.Seconds > 20) {
throw new InvalidOperationException(
"Waited too long (20 seconds) for EventStore node to become master.");
}
Thread.Sleep(1);
}
stopwatch.Stop();
var connection = EmbeddedEventStoreConnection.Create(node);
await connection.ConnectAsync();
var sampleEventData = new EventData(Guid.NewGuid(), "myTestEvent", false, new byte[] { 6, 10, 15 }, null);
WriteResult writeResult = await connection.AppendToStreamAsync("sampleStream, ExpectedVersion.NoStream, sampleEventData);
The stopwatch stuff isn't necessary, but is helpful to break out of the while
loop when something goes wrong and a node never becomes master.
If you put a breakpoint in the event handler delegate, you will notice that the node
progresses through 3 VNodeState
s. First it will be VNodeState.Unknown
, then VNodeState.PreMaster
, then finally VNodeState.Master
.
You also shouldn't need to wait for the node to become master before creating the connection and invoking ConnectAsync()
on it. However, you will need to wait for the node to become master before you can invoke any other methods like AppendToStreamAsync
on it without running into the exception in your original question.