Hello,
I have found an issue with CatchUp subscriptions. When I subscribe for events just after EventStore server is started sometimes new events are not delivered to that subscription.
Subscription is not dropped, just waits infinitely for events. That was tested on in-memory EventStore using following program:
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 10; ++i)
Test(i);
for (int i = 1; i < 30; ++i)
Test(10 + 5 * i);
Console.ReadLine();
}
private static ManualResetEvent connected = new ManualResetEvent(false);
private static void Test(int delay)
{
connected.Reset();
var old = Process.GetProcessesByName("EventStore.ClusterNode");
foreach (var p in old)
p.Kill();
Thread.Sleep(1000);
var path = @"C:\Projects\EventStore";
ProcessStartInfo info = new ProcessStartInfo();
info.Arguments = "--mem-db";
info.FileName = path + @"\EventStore.ClusterNode.exe";
Process.Start(info);
ConnectionSettings cs = ConnectionSettings.Create().
KeepReconnecting().
KeepRetrying().
SetHeartbeatInterval(TimeSpan.FromMinutes(10)).
SetHeartbeatTimeout(TimeSpan.FromMinutes(11)).
WithConnectionTimeoutOf(TimeSpan.FromMinutes(10)).
SetOperationTimeoutTo(TimeSpan.FromMinutes(10)).Build();
IPEndPoint ip = new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 1113);
var connection = EventStoreConnection.Create(cs, ip);
connection.Connected += connection_Connected;
connection.ConnectAsync().Wait();
connected.WaitOne();
Thread.Sleep(delay);
var received = false;
var dropped = false;
EventStoreAllCatchUpSubscription subscription = null;
for (int i = 1; i < 100; ++i)
{
if (subscription == null)
{
subscription = connection.SubscribeToAllFrom(Position.Start, false,
(s, e) =>
{
received = true;
},
null,
(arg1, arg2, arg3) =>
{
dropped = true;
subscription = null;
},
new UserCredentials("admin", "changeit"));
}
Thread.Sleep(50);
}
if (received)
Console.Write("Events received, ");
else
Console.Write("*NO* events received, ");
if (dropped)
Console.Write("dropped, ");
else
Console.Write("not dropped, ");
Console.WriteLine("delay " + delay);
}
static void connection_Connected(object sender, ClientConnectionEventArgs e)
{
connected.Set();
}
}
``
Here is an example output showing when errors appears:
Problem usually occured with subscription with inital delay around 40-100ms. For subscription established after about 2 seconds (when EventStore has completed initailization, based on its output) that error never happened. The reason why EventStore is started manually is that this scenario is used in unit tests.
We have found workaround for that - subscription is tested if it received any events (including system one). If no events appeared in ~200ms, subscription is closed and established again. Is there an other way to make sure, that subscription is established correctly and it will return events ?
Cheers,
Roman.