/// <summary>
        /// Read and process all the table changes from the provided tables.
        ///
        /// Table changes are first read from lower priority to higher priority tables, and subsequently processed
        /// from higher priority tables to lower priority ones. This is made in order to prevent processing changes
        /// from dependent entities that haven't yet been processed (keeping consistency with dependent entities and
        /// the generated events).
        /// For instance, assuming we are processing player wallets and player wallet transactions (wallets have higher
        /// priority than transactions), to prevent reading player wallet transactions from wallets that have not yet been
        /// read we first read changes in player wallet transactions, then we read changes in wallets, then we process the
        /// changes in wallets and finally we process the change in transactions.
        /// </summary>
        /// <param name="conn">The database connection.</param>
        /// <param name="ChangeTrackingContextHandler">Context handler</param>
        private IEnumerable <Change> GetChanges(IDbConnection conn, ChangeTrackingContextHandler contextHandler)
        {
            Stack <IEnumerable <Change> >         tableChanges             = new Stack <IEnumerable <Change> >();
            IEnumerable <TrackedTableInformation> changeTrackingTableInfos = Repository.GetTrackedTablesInformation(conn);

            var currentApplicationOffset = contextHandler.GetContext().ApplicationOffset;
            var dbOffset = contextHandler.GetContext().DatabaseOffset;

            foreach (var changeTrackingTableInfo in changeTrackingTableInfos.OrderBy(x => x.Priority))
            {
                if (!contextHandler.IsMinimalOffsetSupportedHigher(changeTrackingTableInfo.MinValidVersion))
                {
                    var changes = Repository.GetOffsetChanges(conn, changeTrackingTableInfo, currentApplicationOffset, dbOffset);
                    if (changes.Count() != 0)
                    {
                        tableChanges.Push(changes);
                        ContextHandler.RegisterPendingChanges(changes.Count());
                    }
                }
            }

            if (!tableChanges.Any())
            {
                yield return new Change {
                }
            }
            ;                               //  SYNC
            else
            {
                while (tableChanges.Any())
                {
                    foreach (var change in tableChanges.Pop())
                    {
                        yield return(change);

                        ContextHandler.RegisterPendingChanges(-1);
                    }
                }
            }
        }
Exemplo n.º 2
0
 public void Subscribe(ChangeTrackingContextHandler provider)
 {
     Cancellation = provider.Subscribe(this);
 }
 /// <summary>
 /// Change tracking stream constructor
 /// </summary>
 /// <param name="configuration">Change tracking configuration</param>
 /// <param name="stateStorage">Change tracking state storage</param>
 public ChangeTrackingStreamSource(ChangeTrackingConfiguration configuration, StateStorage stateStorage = null)
 {
     this.Repository      = new ChangeTrackingRepository(configuration);
     this.PollingInterval = TimeSpan.FromMilliseconds(configuration.PollIntervalMilliseconds);
     this.ContextHandler  = new ChangeTrackingContextHandler(configuration.ApplicationName, stateStorage ?? new MemoryStateStorage());
 }