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); } } } }
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()); }
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()); }
// 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); } }
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(); } }
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); } }
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); } } } } } }
protected async Task ProcessUncommittedDataEventTransactionAsync(DataEventTransaction dataEventTransaction) { await this.StoreImpactedRecordsInDataEventTransaction(TransactionState.Uncommitted, dataEventTransaction); }