ReadAllEventsBackwardAsync does not return any events

Hi all,

I am using the .NET EventStore.Client (5.0.1) and I need to implement something to replay all events so that my “new” read models can be created by projecting the info of these full history of events.

The problem is that the method does not find any events in EventStore.

This is my code:

public async Task<IEnumerable<IPersistableEvent>> GetAllEvents()
{
    var allResolvedEvents = new List<ResolvedEvent>();
    AllEventsSlice currentSlice;
    var nextSliceStart = Position.Start;
    do
    {
        currentSlice = 
            await _eventStoreConnection.ReadAllEventsBackwardAsync(nextSliceStart, 200, false);
        nextSliceStart = currentSlice.NextPosition;
        var resolvedEvents = currentSlice.Events;
        allResolvedEvents.AddRange(resolvedEvents);
    }
    while (!currentSlice.IsEndOfStream);

    var persistableEvents =
        allResolvedEvents
            .Select(x =>
            {
                var resolvedEventWrapper = _resolvedEventWrapperFactory.Create(x);
                var persistableEvent = _persistableEventMapper.Map(resolvedEventWrapper);
                return persistableEvent;
            })
            .ToList();
    return persistableEvents;
}

I am running a single node locally and I am able to persist events and read from a specific stream properly. This is how I launch the server.

C:\EventStore-OSS-Win-v5.0.1>EventStore.ClusterNode.exe --mem-db

I read somewhere that maybe I should enable projections with

–run-projections=all

but that didn’t make any difference. The documentation here https://eventstore.org/docs/dotnet-api/reading-events/index.html#read-all-events does not mention anything else.

Am I missing something else?

Thanks

In case it makes any difference… I am serializing events to binary, not as Json.

See:

public class EventDataMapper
    : IMapper<IPersistableEvent, EventData>
{
    private readonly IEventSerializationService _eventSerializationService;

    public EventDataMapper(IEventSerializationService eventSerializationService)
    {
        _eventSerializationService = eventSerializationService;
    }

    public EventData Map(IPersistableEvent source)
    {
        var eventType = source.GetType();
        var eventTypeName = eventType.Name;
        var data = _eventSerializationService.ToBytes(source);
        var id = Guid.NewGuid();
        var eventData = new EventData(id, eventTypeName, false, data, null);
        return eventData;
    }
}

public class PersistableEventMapper
: IMapper<IResolvedEvent, IPersistableEvent>
{
private readonly IEventSerializationService _eventSerializationService;

public PersistableEventMapper(IEventSerializationService eventSerializationService)
{
    _eventSerializationService = eventSerializationService;
}

public IPersistableEvent Map(IResolvedEvent source)
{
    var data = source.Data;
    var dataObject = (IPersistableEvent)_eventSerializationService.FromBytes(data);
    return dataObject;
}

}

public class EventSerializationService
: IEventSerializationService
{
public byte[] ToBytes(object obj)
{
if (obj == null) throw new ArgumentNullException(nameof(obj));
var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
var bytes = memoryStream.ToArray();
return bytes;
}
}

public object FromBytes(byte[] bytes)
{
    if (bytes == null) throw new ArgumentNullException(nameof(bytes));
    int length = bytes.Length;
    var binaryFormatter = new BinaryFormatter();
    using (var memoryStream = new MemoryStream())
    {
        memoryStream.Write(bytes, 0, length);
        memoryStream.Seek(0, SeekOrigin.Begin);
        var obj = binaryFormatter.Deserialize(memoryStream);
        return obj;
    }
}

}

ReadAllEventsBackwards(Position.Start ….) will start at the beginning of $all and read backwards… there are no events before the start so it returns nothing.

use Position.End if you really want to ReadAllEventsBackwards.

However, your description of what you are trying to do vs what you are doing doesn’t make much sense to me, maybe I am missing something. If you want to replay events into your readmodel you probably want to use ReadAllEventsForwards(Position.Start …)

Additionally, you probably don’t want to read all the events into a list and then deserialize them, once you get a lot of events, you will probably run out of memory. if you use a catchup subscription, you will get each event in order and can deserialize and apply them one at a time.

Under the hood, a catchup subscription will do a ReadAllForwards to get the events in batches so you will get the same performance as reading them in batches manually.

Additionally, a catchup subscription will not only do this, but continue to receive events once it has caught up to the end of $all.

Hope this helps

Thanks a lot, yes, it was a silly mistake to read the events backwards! Now I can retrieve them properly.

Luckily I asked here, now I know about this catchup subscriptions and will explore it after reading this: https://eventstore.org/blog/20130707/catch-up-subscriptions-with-the-event-store/

Thanks again.

For whoever interested, the subscription mechanism is great for what I want. A Sample console application with the current c# version:

class Program
{
    static async Task Main(string[] args)
    {
        var connectionString = "ConnectTo=tcp://admin:[email protected]:1113; HeartBeatTimeout=500";
        var connectionSettingsBuilder =
            ConnectionSettings
                .Create()
                .KeepReconnecting()
                .SetMaxDiscoverAttempts(int.MaxValue);
        var eventStoreConnection =
            EventStoreConnection.Create(
                connectionString,
                connectionSettingsBuilder);
 
        await eventStoreConnection.ConnectAsync();
 
        CatchUpSubscriptionSettings settings = new CatchUpSubscriptionSettings(int.MaxValue, 10, true, false, "whatever");
        eventStoreConnection.SubscribeToAllFrom(Position.Start, settings, EventAppeared);
 
        await Console.In.ReadLineAsync();
    }
 
    private static async Task EventAppeared(EventStoreCatchUpSubscription eventStoreCatchUpSubscription, ResolvedEvent resolvedEvent)
    {
        var receivedEvent = resolvedEvent.OriginalEvent;
        var streamName = resolvedEvent.OriginalStreamId;
        if (streamName.Contains("Test"))
        {
            await Console.Out.WriteLineAsync($"Received event {receivedEvent.EventNumber} with type {receivedEvent.EventType}");
        }
    }
}