Esempio n. 1
0
        private void CachePage(Page page, string subscriptionId)
        {
            if (IsCachingEnabled)
            {
                IReadOnlyList <Transaction> transactions = page.Transactions;

                // Add to cache in reverse order to prevent other projectors seeing the first transactions on the cache before the entire page is there.
                for (int index = transactions.Count - 1; index > 0; index--)
                {
                    cachedTransactionsByPrecedingCheckpoint.Set(transactions[index - 1].Checkpoint, transactions[index]);
                }

                cachedTransactionsByPrecedingCheckpoint.Set(page.PrecedingCheckpoint, transactions[0]);

                logDebug(() =>
                         $"Cached: (subscription: {subscriptionId}, precedingCheckpoint: {page.PrecedingCheckpoint}, transactions: {transactions.Count}, range: {transactions.First().Checkpoint}-{transactions.Last().Checkpoint}.");
            }
        }
        private async Task <Page> TryLoadNextPage(long previousCheckpoint, string subscriptionId)
        {
            // Maybe it's just loaded to cache.
            try
            {
                Page cachedPage = TryGetNextPageFromCache(previousCheckpoint, subscriptionId);
                if (cachedPage.Transactions.Count > 0)
                {
#if LIQUIDPROJECTIONS_DIAGNOSTICS
                    logger(() => $"Loader for subscription {subscriptionId} has found a page in the cache.");
#endif
                    return(cachedPage);
                }
            }
            catch (Exception exception)
            {
                logger(() =>
                       $"Failed getting transactions after checkpoint {previousCheckpoint} from the cache: " + exception);
            }

            DateTime           timeOfRequestUtc = getUtcNow();
            List <Transaction> transactions;

            try
            {
                transactions = await Task
                               .Run(() => eventStore
                                    .GetFrom((previousCheckpoint == 0) ? (long?)null : previousCheckpoint)
                                    .Take(maxPageSize)
                                    .ToList())
                               .ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                logger(() => $"Failed loading transactions after checkpoint {previousCheckpoint} from NEventStore: " +
                       exception);

                throw;
            }

            if (transactions.Count > 0)
            {
#if LIQUIDPROJECTIONS_DIAGNOSTICS
                logger(() =>
                       $"Loader for subscription {subscriptionId ?? "without ID"} has loaded {transactions.Count} transactions " +
                       $"from checkpoint {transactions.First().Checkpoint} to checkpoint {transactions.Last().Checkpoint}.");
#endif

                if (transactionCacheByPreviousCheckpoint != null)
                {
                    /* 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--)
                    {
                        transactionCacheByPreviousCheckpoint.Set(transactions[index - 1].Checkpoint, transactions[index]);
                    }

                    transactionCacheByPreviousCheckpoint.Set(previousCheckpoint, transactions[0]);

#if LIQUIDPROJECTIONS_DIAGNOSTICS
                    logger(() =>
                           $"Loader for subscription {subscriptionId ?? "without ID"} has cached {transactions.Count} transactions " +
                           $"from checkpoint {transactions.First().Checkpoint} to checkpoint {transactions.Last().Checkpoint}.");
#endif
                }
            }
            else
            {
#if LIQUIDPROJECTIONS_DIAGNOSTICS
                logger(() =>
                       $"Loader for subscription {subscriptionId} has discovered " +
                       $"that there are no new transactions yet. Next request for the new transactions will be delayed.");
#endif

                Volatile.Write(
                    ref lastSuccessfulPollingRequestWithoutResults,
                    new CheckpointRequestTimestamp(previousCheckpoint, timeOfRequestUtc));
            }

            return(new Page(previousCheckpoint, transactions));
        }