diff --git a/LiquidProjections.PollingEventStore.sln.DotSettings b/LiquidProjections.PollingEventStore.sln.DotSettings index d11f4a1..69e86cc 100644 --- a/LiquidProjections.PollingEventStore.sln.DotSettings +++ b/LiquidProjections.PollingEventStore.sln.DotSettings @@ -7,6 +7,7 @@ Required Required Required + NEVER False True 130 @@ -55,7 +56,12 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + True + True True + True True True True diff --git a/README.MD b/README.MD index 9897bfa..bb3a1ab 100644 --- a/README.MD +++ b/README.MD @@ -1,4 +1,8 @@ # Liquid Projections [![Build status](https://ci.appveyor.com/api/projects/status/5j2rboeh9vg8773w/branch/master?svg=true)](https://ci.appveyor.com/project/dennisdoomen/liquidprojections-pollingeventstore-ctw8n/branch/master) ## What is this? -An adapter for event stores that cannot actively push events to [LiquidProjections](https://github.com/liquidprojections/LiquidProjections). It efficiently support multiple concurrent subscribers each interested in a different checkpoint without hitting the underlying event store concurrently \ No newline at end of file +A source-only Nuget package for event stores that cannot actively push events to [LiquidProjections](https://github.com/liquidprojections/LiquidProjections). It efficiently support multiple concurrent subscribers each interested in a different checkpoint without hitting the underlying event store concurrently. + +## Important Notes +* This library uses [Liblog](https://github.com/damianh/LibLog) to log details about asynchronous exceptions to your logging framework of choice. You can also have it log more diagnostic messages by setting the `LIQUIDPROJECTIONS_DIAGNOSTICS` condition symbol. +* If you use this library inside your own packaged library, make sure you set the `LIBLOG_PROVIDERS_ONLY` compiler symbol to prevent the LibLog package from leaking into your consumers. \ No newline at end of file diff --git a/Src/LiquidProjections.PollingEventStore/LibLog.cs b/Src/LiquidProjections.PollingEventStore/LibLog.cs index 3aa4bb3..3e5cf40 100644 --- a/Src/LiquidProjections.PollingEventStore/LibLog.cs +++ b/Src/LiquidProjections.PollingEventStore/LibLog.cs @@ -40,23 +40,23 @@ using System.Diagnostics.CodeAnalysis; -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "LiquidProjections.NEventStore.Logging")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "LiquidProjections.NEventStore.Logging.Logger.#Invoke(LiquidProjections.NEventStore.Logging.LogLevel,System.Func`1,System.Exception,System.Object[])")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "LiquidProjections.PollingEventStoreAdapter.Logging")] +[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "LiquidProjections.PollingEventStoreAdapter.Logging.Logger.#Invoke(LiquidProjections.PollingEventStoreAdapter.Logging.LogLevel,System.Func`1,System.Exception,System.Object[])")] // If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries // that use LibLog #if LIBLOG_PROVIDERS_ONLY -namespace LiquidProjections.NEventStore.LibLog +namespace LiquidProjections.PollingEventStoreAdapter.LibLog #else -namespace LiquidProjections.NEventStore.Logging +namespace LiquidProjections.PollingEventStoreAdapter.Logging #endif { using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; #if LIBLOG_PROVIDERS_ONLY - using LiquidProjections.NEventStore.LibLog.LogProviders; + using LiquidProjections.PollingEventStoreAdapter.LibLog.LogProviders; #else - using LiquidProjections.NEventStore.Logging.LogProviders; + using LiquidProjections.PollingEventStoreAdapter.Logging.LogProviders; #endif using System; #if !LIBLOG_PROVIDERS_ONLY @@ -714,9 +714,9 @@ public bool Log(LogLevel logLevel, Func messageFunc, Exception exception } #if LIBLOG_PROVIDERS_ONLY -namespace LiquidProjections.NEventStore.LibLog.LogProviders +namespace LiquidProjections.PollingEventStoreAdapter.LibLog.LogProviders #else -namespace LiquidProjections.NEventStore.Logging.LogProviders +namespace LiquidProjections.PollingEventStoreAdapter.Logging.LogProviders #endif { using System; diff --git a/Src/LiquidProjections.PollingEventStore/LiquidProjections.PollingEventStore.csproj b/Src/LiquidProjections.PollingEventStore/LiquidProjections.PollingEventStore.csproj index 600f179..c38bee5 100644 --- a/Src/LiquidProjections.PollingEventStore/LiquidProjections.PollingEventStore.csproj +++ b/Src/LiquidProjections.PollingEventStore/LiquidProjections.PollingEventStore.csproj @@ -1,21 +1,16 @@  - netstandard1.1 - - TRACE;RELEASE;NETSTANDARD1_1;LIBLOG_PORTABLE + TRACE;RELEASE;NETSTANDARD1_1;LIBLOG_PORTABLE;RELEASE;NETSTANDARD1_1;LIQUIDPROJECTIONS_BUILD_TIME - - TRACE;DEBUG;NETSTANDARD1_1;LIBLOG_PORTABLE + TRACE;DEBUG;NETSTANDARD1_1;LIBLOG_PORTABLE;DEBUG;NETSTANDARD1_1;LIQUIDPROJECTIONS_BUILD_TIME;LIQUIDPROJECTIONS_DIAGNOSTICS - - \ No newline at end of file diff --git a/Src/LiquidProjections.PollingEventStore/PollingEventStoreAdapter.cs b/Src/LiquidProjections.PollingEventStore/PollingEventStoreAdapter.cs index fc542bc..efaba12 100644 --- a/Src/LiquidProjections.PollingEventStore/PollingEventStoreAdapter.cs +++ b/Src/LiquidProjections.PollingEventStore/PollingEventStoreAdapter.cs @@ -4,7 +4,7 @@ using System.Threading; using System.Threading.Tasks; using LiquidProjections.Abstractions; -using LiquidProjections.NEventStore.Logging; +using LiquidProjections.PollingEventStoreAdapter.Logging; namespace LiquidProjections.PollingEventStore { @@ -16,7 +16,12 @@ namespace LiquidProjections.PollingEventStore /// If the implementation of implements , disposing /// the will also dispose the event store. /// - public class PollingEventStoreAdapter : IDisposable +#if LIQUIDPROJECTIONS_BUILD_TIME + public +#else + internal +#endif + class PollingEventStoreAdapter : IDisposable { private readonly TimeSpan pollInterval; private readonly int maxPageSize; @@ -138,7 +143,7 @@ private Page TryGetNextPageFromCache(long previousCheckpoint, string subscriptio } } -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Subscription {subscriptionId} has found a page of size {resultPage.Count} " + $"from checkpoint {resultPage.First().Checkpoint} " + @@ -148,7 +153,7 @@ private Page TryGetNextPageFromCache(long previousCheckpoint, string subscriptio return new Page(previousCheckpoint, resultPage); } -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Subscription {subscriptionId} has not found the next transaction in the cache."); #endif @@ -158,7 +163,7 @@ private Page TryGetNextPageFromCache(long previousCheckpoint, string subscriptio private void StartPreloadingNextPage(long previousCheckpoint, string subscriptionId) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Subscription {subscriptionId} has started preloading transactions " + $"after checkpoint {previousCheckpoint}."); @@ -174,7 +179,7 @@ private async Task LoadNextPageSequentially(long previousCheckpoint, strin { if (isDisposed) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Page loading for subscription {subscriptionId} cancelled because the adapter is disposed."); #endif @@ -193,7 +198,7 @@ private async Task LoadNextPageSequentially(long previousCheckpoint, strin { TimeSpan delay = pollInterval - timeAfterPreviousRequest; -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Subscription {subscriptionId} is waiting " + $"for {delay} before checking for new transactions."); @@ -242,7 +247,7 @@ private Task TryLoadNextPageSequentiallyOrWaitForCurrentLoadingToFinish(lo { if (isTaskOwner) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)) .Debug(() => $"Subscription {subscriptionId} created a loader {loader.Id} " + $"for a page after checkpoint {previousCheckpoint}."); @@ -250,7 +255,7 @@ private Task TryLoadNextPageSequentiallyOrWaitForCurrentLoadingToFinish(lo if (isDisposed) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)) .Debug(() => $"The loader {loader.Id} is cancelled because the adapter is disposed."); #endif @@ -267,7 +272,7 @@ private Task TryLoadNextPageSequentiallyOrWaitForCurrentLoadingToFinish(lo } else { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)) .Debug(() => $"Subscription {subscriptionId} is waiting for loader {loader.Id}."); #endif @@ -288,7 +293,7 @@ private async Task TryLoadNextPageAndMakeLoaderComplete(long previousCheckpoint, } finally { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Loader for subscription {subscriptionId} is no longer the current one."); #endif @@ -297,7 +302,7 @@ private async Task TryLoadNextPageAndMakeLoaderComplete(long previousCheckpoint, } catch (Exception exception) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).DebugException( $"Loader for subscription {subscriptionId} has failed.", exception); @@ -307,7 +312,7 @@ private async Task TryLoadNextPageAndMakeLoaderComplete(long previousCheckpoint, return; } -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Loader for subscription {subscriptionId} has completed."); #endif @@ -322,7 +327,7 @@ private async Task TryLoadNextPage(long previousCheckpoint, string subscri Page cachedPage = TryGetNextPageFromCache(previousCheckpoint, subscriptionId); if (cachedPage.Transactions.Count > 0) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)) .Debug(() => $"Loader for subscription {subscriptionId} has found a page in the cache."); @@ -362,7 +367,7 @@ private async Task TryLoadNextPage(long previousCheckpoint, string subscri if (transactions.Count > 0) { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Loader for subscription {subscriptionId ?? "without ID"} has loaded {transactions.Count} transactions " + $"from checkpoint {transactions.First().Checkpoint} to checkpoint {transactions.Last().Checkpoint}."); @@ -370,7 +375,7 @@ private async Task TryLoadNextPage(long previousCheckpoint, string subscri if (transactionCacheByPreviousCheckpoint != null) { - /* Add to cache in reverse order to prevent other projectors + /* Add to cache in reverse order to prevent other projectors from requesting already loaded transactions which are not added to cache yet. */ for (int index = transactions.Count - 1; index > 0; index--) { @@ -379,7 +384,7 @@ from requesting already loaded transactions which are not added to cache yet. */ transactionCacheByPreviousCheckpoint.Set(previousCheckpoint, transactions[0]); -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Loader for subscription {subscriptionId ?? "without ID"} has cached {transactions.Count} transactions " + $"from checkpoint {transactions.First().Checkpoint} to checkpoint {transactions.Last().Checkpoint}."); @@ -388,7 +393,7 @@ from requesting already loaded transactions which are not added to cache yet. */ } else { -#if DEBUG +#if LIQUIDPROJECTIONS_DIAGNOSTICS LogProvider.GetLogger(typeof(PollingEventStoreAdapter)).Debug(() => $"Loader for subscription {subscriptionId} has discovered " + $"that there are no new transactions yet. Next request for the new transactions will be delayed."); diff --git a/Src/LiquidProjections.PollingEventStore/Subscription.cs b/Src/LiquidProjections.PollingEventStore/Subscription.cs index 7060f87..0f060bb 100644 --- a/Src/LiquidProjections.PollingEventStore/Subscription.cs +++ b/Src/LiquidProjections.PollingEventStore/Subscription.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; using LiquidProjections.Abstractions; -using LiquidProjections.NEventStore.Logging; +using LiquidProjections.PollingEventStoreAdapter.Logging; namespace LiquidProjections.PollingEventStore {