예제 #1
0
        public async Task CommitAsync()
        {
            DataEventTransaction dataEventTransaction = this.dataEvents.Count > 0 ? new DataEventTransaction(DateTime.Now, this.dataEvents.ToArray()) : null;

            if (dataEventTransaction != null)
            {
                await this.database.PostDataEventTransactionAsync(TransactionState.Uncommitted, dataEventTransaction);
            }
            await this.DoCommitAsync();

            if (dataEventTransaction != null)
            {
                await this.database.PostDataEventTransactionAsync(TransactionState.Committed, dataEventTransaction);
            }

            HashSet <string> onCommitKeys = new HashSet <string>();

            foreach (var onCommitRef in this.onCommitRefs)
            {
                if (onCommitRef.key == null || !onCommitKeys.Contains(onCommitRef.key))
                {
                    await onCommitRef.onCommit();

                    if (onCommitRef.key != null)
                    {
                        onCommitKeys.Add(onCommitRef.key);
                    }
                }
            }
        }
예제 #2
0
        protected async Task ProcessCommittedDataEventTransactionAsync(DataEventTransaction dataEventTransaction)
        {
            logger.Trace($"ProcessCommittedDataEventTransactionAsync():dataEventTransaction={dataEventTransaction}");
            await this.StoreImpactedRecordsInDataEventTransaction(TransactionState.Committed, dataEventTransaction);

            this.incomingDataEventTransactions.Enqueue(dataEventTransaction);
            this.monitor.PulseAll();
        }
        internal void PostDataEventTransaction(TransactionState transactionState, DataEventTransaction dataEventTransaction)
        {
            // Use ToArray() to avoid the collection being modified during the loop
            DataEventTransactionListener[] listeners = transactionState == TransactionState.Uncommitted ? this.uncommittedTransactionListeners.ToArray() : this.committedTransactionListeners.ToArray();

            listeners.Where(x => x.listener != null).AsParallel().ForAll(x => x.listener(dataEventTransaction));
            Task[] tasks = listeners.Where(x => x.listenerAsync != null).Select(x => x.listenerAsync(dataEventTransaction)).ToArray();
            Task.WaitAll(tasks.ToArray());
        }
예제 #4
0
        protected DataEvent[] CreateDynamicViewDataEvents(DataEventTransaction dataEventTransaction, DynamicView dynamicView)
        {
            logger.Trace($"RunAsync():dynamicView.name={dynamicView.Name}");
            List <DataEvent> newRecordDataEvents = new List <DataEvent>();

            // Don't send data events if DynamicView has dirty params because
            // the DynamicView will be requeried anyways
            if (!dynamicView.HasDirtyParams)
            {
                HashSet <string> newRecordDataEventFullKeys = new HashSet <string>();
                foreach (var dataEvent in dataEventTransaction.dataEvents)
                {
                    if (dataEvent is KeyValueDataEvent keyValueDataEvent && dynamicView.TryGetDynamicStatementFromRef(keyValueDataEvent.name, out StatementFromRef dynamicStatementFromRef))
                    {
                        // Fetch the preCommitImpactedRecords
                        Dict[] preCommitImpactedRecords = null;
                        if (HasImpactedRecords(TransactionState.Uncommitted, dataEvent, dynamicStatementFromRef.joinType))
                        {
                            string storageKey = GetImpactedRecordsStorageKey(dynamicView, dataEvent, TransactionState.Uncommitted);
                            preCommitImpactedRecords = (Dict[])dataEventTransaction.Fetch(storageKey);
                        }

                        // Fetch the postCommitImpactedRecords
                        Dict[] postCommitImpactedRecords = null;
                        if (HasImpactedRecords(TransactionState.Committed, dataEvent, dynamicStatementFromRef.joinType))
                        {
                            string storageKey = GetImpactedRecordsStorageKey(dynamicView, dataEvent, TransactionState.Committed);
                            postCommitImpactedRecords = (Dict[])dataEventTransaction.Fetch(storageKey);
                        }

                        // Determine the changes from each data event on each dynamic select
                        RecordDataEvent[] recordDataEvents = dynamicView.ProcessDataChange(dataEvent, preCommitImpactedRecords, postCommitImpactedRecords);
                        if (recordDataEvents != null)
                        {
                            dynamicView.UpdateChildDynamicParams(recordDataEvents);
                            foreach (var recordDataEvent in recordDataEvents)
                            {
                                string fullKey = $"{recordDataEvent.name}:{recordDataEvent.keyValue}";
                                if (!newRecordDataEventFullKeys.Contains(fullKey))
                                {
                                    newRecordDataEventFullKeys.Add(fullKey);
                                    newRecordDataEvents.Add(recordDataEvent);
                                }
                            }
                        }
                    }
                }
            }

            return(newRecordDataEvents.ToArray());
        }
예제 #5
0
        // Commit methods
        public void Commit()
        {
            DataEventTransaction dataEventTransaction = this.dataEvents.Count > 0 ? new DataEventTransaction(DateTime.Now, this.dataEvents.ToArray()) : null;

            if (dataEventTransaction != null)
            {
                this.database.PostDataEventTransaction(TransactionState.Uncommitted, dataEventTransaction);
            }
            this.DoCommit();
            if (dataEventTransaction != null)
            {
                this.database.PostDataEventTransaction(TransactionState.Committed, dataEventTransaction);
            }
        }
예제 #6
0
        public async Task CommitAsync()
        {
            DataEventTransaction dataEventTransaction = this.dataEvents.Count > 0 ? new DataEventTransaction(DateTime.Now, this.dataEvents.ToArray()) : null;

            if (dataEventTransaction != null)
            {
                await this.database.PostDataEventTransactionAsync(TransactionState.Uncommitted, dataEventTransaction);
            }
            await this.DoCommitAsync();

            if (dataEventTransaction != null)
            {
                await this.database.PostDataEventTransactionAsync(TransactionState.Committed, dataEventTransaction);
            }

            foreach (var onCommit in this.onCommits)
            {
                await onCommit();
            }
        }
예제 #7
0
        protected async Task SendToListenerAsync(DataEventTransaction dataEventTransaction)
        {
            if (logger.IsTraceEnabled)
            {
                logger.Trace($"SendToListenerAsync():dataEventTransaction={dataEventTransaction}");
            }
            else if (logger.IsDebugEnabled)
            {
                logger.Debug($"SendToListenerAsync():dataEventTransaction.dataEvents.Length={dataEventTransaction.dataEvents.Length}");
            }

            if (this.listener != null)
            {
                this.listener(dataEventTransaction);
            }
            if (this.asyncListener != null)
            {
                await asyncListener(dataEventTransaction);
            }
        }
예제 #8
0
        protected async Task StoreImpactedRecordsInDataEventTransaction(TransactionState transactionState, DataEventTransaction dataEventTransaction)
        {
            foreach (var dynamicView in this.dynamicViews)
            {
                foreach (var dataEvent in dataEventTransaction.dataEvents)
                {
                    if (dataEvent is KeyValueDataEvent keyValueDataEvent && dynamicView.TryGetDynamicStatementFromRef(keyValueDataEvent.name, out StatementFromRef dynamicStatementFromRef))
                    {
                        if (HasImpactedRecords(transactionState, keyValueDataEvent, dynamicStatementFromRef.joinType))
                        {
                            Dict[] impactedRecords = await dynamicView.GetImpactedRecordsAsync(keyValueDataEvent);

                            if (impactedRecords != null && impactedRecords.Length > 0)
                            {
                                string storageKey = GetImpactedRecordsStorageKey(dynamicView, dataEvent, transactionState);
                                dataEventTransaction.Store(storageKey, impactedRecords);
                            }
                        }
                    }
                }
            }
        }
예제 #9
0
 protected async Task ProcessUncommittedDataEventTransactionAsync(DataEventTransaction dataEventTransaction)
 {
     await this.StoreImpactedRecordsInDataEventTransaction(TransactionState.Uncommitted, dataEventTransaction);
 }