hakksor
hakksor

Reputation: 1380

BeforeStore doesn't work for async sessions in RavenDB 4?

I've been migrating my code to RavenDB 4.

I noticed that listeners in RavenDB 4 has changed since version 3. In v3 you used IDocumentStoreListener and RegisterListener but in v4 you subscribe to the BeforeStore event directly on the session instance.

However, my BeforeStore-event listener doesn't fire on an async session (but does on a synchronous one). Is this by design, or is it something I'm missing?

I'm using version 4.0.0-rc-40025 of both RavenDB Client (.NET) and server.

Thanks!

Here is a sample console application which recreates the issue:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Raven.Client.Documents;

namespace BeforeStoreAsync
{
    class Program
    {
        static void Main(string[] args)
        {

            IDocumentStore store = new DocumentStore
            {
                Urls = new[] { "http://localhost:8080" },
                Database = "MyDatabase"
            };

            store.OnBeforeStore += (sender, eventArgs) =>
            {
                if (eventArgs.Entity is MyEntity entity)
                    entity.Description = DateTime.UtcNow.ToString();
            };

            store = store.Initialize();

            var syncEntity = StoreEntitySync(store);
            var asyncEntity = StoreEntityAsync(store).Result;

            if (string.IsNullOrWhiteSpace(syncEntity.Description))
                Console.WriteLine($"BeforeStore didn't run for {nameof(syncEntity)}.");

            if (string.IsNullOrWhiteSpace(asyncEntity.Description))
                Console.WriteLine($"BeforeStore didn't run for {nameof(asyncEntity)}.");
        }

        private static MyEntity StoreEntitySync(IDocumentStore store)
        {
            using(var session = store.OpenSession())
            {
                var entity = new MyEntity
                {
                    Name = "Sync session"
                };

                session.Store(entity);
                session.SaveChanges();

                return entity;
            }
        }

        private static async Task<MyEntity> StoreEntityAsync(IDocumentStore store)
        {
            using (var session = store.OpenAsyncSession())
            {
                var entity = new MyEntity
                {
                    Name = "Async session"
                };

                await session.StoreAsync(entity);
                await session.SaveChangesAsync();

                return entity;
            }
        }
    }

    public class MyEntity
    {
        public string Name { get; set; }
        public string Description { get; set; }

        public string Id { get; set; }
    }
}

The above example will output the following to console:

BeforeStore didn't run for asyncEntity.

Upvotes: 2

Views: 319

Answers (1)

Ayende Rahien
Ayende Rahien

Reputation: 22956

No, this is called in all cases. In fact, the actual calling mechanism isn't inside the Store at all, but is called during the SaveChanges or SaveChangesAsync

Upvotes: 1

Related Questions