private void NotifySubscribers(string type, BlittableJsonReaderObject value, List <DatabaseConnectionState> states) { switch (type) { case nameof(DocumentChange): var documentChange = DocumentChange.FromJson(value); foreach (var state in states) { state.Send(documentChange); } break; case nameof(IndexChange): var indexChange = IndexChange.FromJson(value); foreach (var state in states) { state.Send(indexChange); } break; case nameof(OperationStatusChange): var operationStatusChange = OperationStatusChange.FromJson(value, _conventions); foreach (var state in states) { state.Send(operationStatusChange); } break; default: throw new NotSupportedException(type); } }
private void RaiseNotifications(OperationStatusChange change, Operation operation) { var operationChanged = OperationChanged.Create(_name, change.OperationId, operation.Description, change.State, operation.Killable); operation.NotifyCenter(operationChanged, x => _notificationCenter.Add(x)); _changes?.RaiseNotifications(change); }
public void RaiseNotifications(OperationStatusChange operationStatusChange) { OnOperationStatusChange?.Invoke(operationStatusChange); foreach (var connection in Connections) { connection.Value.SendOperationStatusChangeNotification(operationStatusChange); } }
public void SendOperationStatusChangeNotification(OperationStatusChange change) { if (_watchAllOperations > 0) { Send(change); return; } if (_matchingOperations.Contains(change.OperationId)) { Send(change); } }
private void NotifySubscribers(string type, BlittableJsonReaderObject value, List <DatabaseConnectionState> states) { switch (type) { case nameof(DocumentChange): var documentChange = DocumentChange.FromJson(value); foreach (var state in states) { state.Send(documentChange); } break; case nameof(CounterChange): var counterChange = CounterChange.FromJson(value); foreach (var state in states) { state.Send(counterChange); } break; case nameof(IndexChange): var indexChange = IndexChange.FromJson(value); foreach (var state in states) { state.Send(indexChange); } break; case nameof(OperationStatusChange): var operationStatusChange = OperationStatusChange.FromJson(value, _conventions); foreach (var state in states) { state.Send(operationStatusChange); } break; case nameof(TopologyChange): var topologyChange = TopologyChange.FromJson(value); _requestExecutor?.UpdateTopologyAsync(new ServerNode { Url = topologyChange.Url, Database = topologyChange.Database }, 0, true, "topology-change-notification").ConfigureAwait(false); break; default: throw new NotSupportedException(type); } }
private void Send(OperationStatusChange change) { var value = new DynamicJsonValue { ["Type"] = nameof(OperationStatusChange), ["Value"] = change.ToJson() }; if (_disposeToken.IsCancellationRequested == false) { _sendQueue.Enqueue(new ChangeValue { ValueToSend = value, AllowSkip = false }); } }
private void NotifySubscribers(string type, BlittableJsonReaderObject value, List <DatabaseConnectionState> states) { switch (type) { case nameof(DocumentChange): var documentChange = DocumentChange.FromJson(value); foreach (var state in states) { state.Send(documentChange); } break; case nameof(CounterChange): var counterChange = CounterChange.FromJson(value); foreach (var state in states) { state.Send(counterChange); } break; case nameof(TimeSeriesChange): var timeSeriesChange = TimeSeriesChange.FromJson(value); foreach (var state in states) { state.Send(timeSeriesChange); } break; case nameof(IndexChange): var indexChange = IndexChange.FromJson(value); foreach (var state in states) { state.Send(indexChange); } break; case nameof(OperationStatusChange): var operationStatusChange = OperationStatusChange.FromJson(value); foreach (var state in states) { state.Send(operationStatusChange); } break; case nameof(TopologyChange): var topologyChange = TopologyChange.FromJson(value); var requestExecutor = _requestExecutor; if (requestExecutor != null) { var node = new ServerNode { Url = topologyChange.Url, Database = topologyChange.Database }; requestExecutor.UpdateTopologyAsync(new RequestExecutor.UpdateTopologyParameters(node) { TimeoutInMs = 0, ForceUpdate = true, DebugTag = "topology-change-notification" }).ConfigureAwait(false); } break; default: throw new NotSupportedException(type); } }
public Task <IOperationResult> AddOperation( DocumentDatabase database, string description, OperationType operationType, Func <Action <IOperationProgress>, Task <IOperationResult> > taskFactory, long id, IOperationDetailedDescription detailedDescription = null, OperationCancelToken token = null) { var operationState = new OperationState { Status = OperationStatus.InProgress }; var notification = new OperationStatusChange { OperationId = id, State = operationState }; var operationDescription = new OperationDescription { Description = description, TaskType = operationType, StartTime = SystemTime.UtcNow, DetailedDescription = detailedDescription }; var operation = new Operation { Database = database, Id = id, Description = operationDescription, Token = token, State = operationState }; object locker = new object(); Monitor.Enter(locker); try { operation.Task = Task.Run(() => taskFactory(ProgressNotification)); operation.Task.ContinueWith(ContinuationFunction); _active.TryAdd(id, operation); if (token == null) { return(operation.Task); } return(operation.Task.ContinueWith(t => { token.Dispose(); return t; }).Unwrap()); } finally { Monitor.Exit(locker); } void ContinuationFunction(Task <IOperationResult> taskResult) { operationDescription.EndTime = SystemTime.UtcNow; operationState.Progress = null; if (taskResult.IsCanceled) { operationState.Result = null; operationState.Status = OperationStatus.Canceled; } else if (taskResult.IsFaulted) { var innerException = taskResult.Exception.ExtractSingleInnerException(); var isConflict = innerException is DocumentConflictException || innerException is ConcurrencyException; var status = isConflict ? HttpStatusCode.Conflict : HttpStatusCode.InternalServerError; var shouldPersist = false; switch (operationType) { case OperationType.DatabaseExport: case OperationType.DatabaseImport: shouldPersist = true; break; } operationState.Result = new OperationExceptionResult(innerException, status, shouldPersist); operationState.Status = OperationStatus.Faulted; } else { operationState.Result = taskResult.Result; operationState.Status = OperationStatus.Completed; } if (Monitor.TryEnter(locker) == false) { // adding of operation still didn't finish, just exit RaiseNotifications(notification, operation); return; } try { if (_active.TryGetValue(id, out Operation completed)) { completed.SetCompleted(); // add to completed items before removing from active ones to ensure an operation status is accessible all the time _completed.TryAdd(id, completed); _active.TryRemove(id, out completed); } RaiseNotifications(notification, operation); } finally { Monitor.Exit(locker); } } void ProgressNotification(IOperationProgress progress) { notification.State.Progress = progress; RaiseNotifications(notification, operation); } }
public Task <IOperationResult> AddOperation( DocumentDatabase database, string description, OperationType operationType, Func <Action <IOperationProgress>, Task <IOperationResult> > taskFactory, long id, OperationCancelToken token = null) { var operationState = new OperationState { Status = OperationStatus.InProgress }; var notification = new OperationStatusChange { OperationId = id, State = operationState }; var operationDescription = new OperationDescription { Description = description, TaskType = operationType, StartTime = SystemTime.UtcNow }; var operation = new Operation { Database = database, Id = id, Description = operationDescription, Token = token, State = operationState }; void ProgressNotification(IOperationProgress progress) { notification.State.Progress = progress; RaiseNotifications(notification, operation); } operation.Task = taskFactory(ProgressNotification); operation.Task.ContinueWith(taskResult => { operationDescription.EndTime = SystemTime.UtcNow; operationState.Progress = null; if (taskResult.IsCanceled) { operationState.Result = null; operationState.Status = OperationStatus.Canceled; } else if (taskResult.IsFaulted) { var innerException = taskResult.Exception.ExtractSingleInnerException(); var isConflict = innerException is DocumentConflictException || innerException is ConcurrencyException; var status = isConflict ? HttpStatusCode.Conflict : HttpStatusCode.InternalServerError; var shouldPersist = false; switch (operationType) { case OperationType.DatabaseExport: case OperationType.DatabaseImport: shouldPersist = true; break; } operationState.Result = new OperationExceptionResult(innerException, status, shouldPersist); operationState.Status = OperationStatus.Faulted; } else { operationState.Result = taskResult.Result; operationState.Status = OperationStatus.Completed; } if (_active.TryGetValue(id, out Operation completed)) { // add to completed items before removing from active ones to ensure an operation status is accessible all the time _completed.TryAdd(id, completed); _active.TryRemove(id, out completed); } RaiseNotifications(notification, operation); }); _active.TryAdd(id, operation); return(operation.Task); }
void OnUpdatedOperationStatus(bool inProgress) { OperationStatusChange?.Invoke(inProgress); }
public void Send(OperationStatusChange operationStatusChange) { OnOperationStatusChangeNotification?.Invoke(operationStatusChange); }