Skip to content

Instantly share code, notes, and snippets.

@tomliversidge
Created May 7, 2017 13:31
Show Gist options
  • Save tomliversidge/b774c266a922b23bf08c19c6a83d5339 to your computer and use it in GitHub Desktop.
Save tomliversidge/b774c266a922b23bf08c19c6a83d5339 to your computer and use it in GitHub Desktop.
Utter madness, or great implementation of interface segregation principal?
namespace Proto.Persistence
{
public interface IProvider : IEventSourcingProvider, ISnapshotProvider { }
public interface IEventSourcingProvider : IModifyEvents, IGetEvents { }
public interface IModifyEvents
{
Task PersistEventAsync(string actorName, long index, object @event);
Task DeleteEventsAsync(string actorName, long inclusiveToIndex);
}
public interface IGetEvents
{
Task GetEventsAsync(string actorName, long indexStart, Action<object> callback);
}
public interface ISnapshotProvider : IGetSnapshots, IModifySnapshots { }
public interface IGetSnapshots
{
Task<(object Snapshot, long Index)> GetSnapshotAsync(string actorName);
}
public interface IModifySnapshots
{
Task PersistSnapshotAsync(string actorName, long index, object snapshot);
Task DeleteSnapshotsAsync(string actorName, long inclusiveToIndex);
}
}
// example usages: logging, security, caching etc..
public class DecoratedSnapshotter : ISnapshotProvider
{
private readonly IGetSnapshots _getter;
private readonly IModifySnapshots _modifier;
public DecoratedSnapshotter(IGetSnapshots getter, IModifySnapshots modifier)
{
_getter = getter;
_modifier = modifier;
}
public Task<(object Snapshot, long Index)> GetSnapshotAsync(string actorName)
{
return _getter.GetSnapshotAsync(actorName);
}
public Task PersistSnapshotAsync(string actorName, long index, object snapshot)
{
return _modifier.PersistSnapshotAsync(actorName, index, snapshot);
}
public Task DeleteSnapshotsAsync(string actorName, long inclusiveToIndex)
{
return _modifier.DeleteSnapshotsAsync(actorName, inclusiveToIndex);
}
}
public class CachedSnapshotGetter : IGetSnapshots
{
private readonly IGetSnapshots _getter;
private readonly Dictionary<string, (long, object)> _cache;
public CachedSnapshotGetter(IGetSnapshots getter, Dictionary<string, (long Index, object Snapshot)> cache)
{
_getter = getter;
_cache = cache;
}
public Task<(object Snapshot, long Index)> GetSnapshotAsync(string actorName)
{
if (_cache.ContainsKey(actorName))
{
return Task.FromResult((_cache[actorName].Item2, _cache[actorName].Item1));
}
else
{
return _getter.GetSnapshotAsync(actorName);
}
}
public static DecoratedSnapshotter Use(IGetSnapshots getter, IModifySnapshots modifier)
{
return new DecoratedSnapshotter(new CachedSnapshotGetter(getter, new Dictionary<string, (long Index, object Snapshot)>()), modifier);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment