protected override async Task <AcquisitionActionResult> InitializeCore(InitializeAcquisitionParameter parameters, AcquisitionActionResult result) { result = await base.InitializeCore(parameters, result).ConfigureAwait(false); // get initial value of IsTransferring await Task.WhenAll(AgentBroker.Instance.TryExecuteOnAll <IFileTransferAgent, bool>(a => a.IsTransferring).GetValueOrDefault()) .ContinueWith(t => _isTransferringSubject.OnNext(t.Result.Any(_ => _)), TaskContinuationOptions.OnlyOnRanToCompletion) .ConfigureAwait(false); return(result); }
private void btnDisplayMode_Click(object sender, EventArgs e) { if (_uiThemeSubject.Value.DisplayMode == DisplayMode.Day) { btnDisplayMode.Image = ImageResources.ServiceDisplayDay; _uiThemeSubject.OnNext(_uiThemes[DisplayMode.Night]); } else { btnDisplayMode.Image = ImageResources.ServiceDisplayNight; _uiThemeSubject.OnNext(_uiThemes[DisplayMode.Day]); } }
private async Task <bool> MakeStateTransition(IEnumerable <AgentState> validStates, AgentState intermediateState, AgentState toState, Func <Task <bool> > action) { if (validStates == null) { throw new ArgumentNullException("validStates"); } var fromState = this.State; if (this.State == AgentState.Failed) { Log.Warn().Message("AgentState transition ('{0}->{1}') tried on an agent in a failed state.", intermediateState, toState).WithAgent(this).Write(); return(false); } if (!validStates.Contains(fromState)) { throw new InvalidOperationException(string.Format("Current state '{0}' is invalid, it must be one of the following: '{1}'.", fromState, string.Join("','", validStates))); } Log.Debug().Message("Transition AgentState intermédiaire: {0}->{1}.", fromState, intermediateState).WithAgent(this).Write(); _stateSubject.OnNext(intermediateState); bool result = false; try { result = (action == null) ? true : await action().ConfigureAwait(false); } finally { Log.Level(result ? LogLevel.Debug : LogLevel.Warn).Message("AgentState transition {3}: {0}->{1}->{2}.", fromState, intermediateState, toState, result ? "was successful" : "failed").WithAgent(this).Write(); if (result) { _stateSubject.OnNext(toState); } else { _stateSubject.OnNext(AgentState.Failed); } } return(result); }
public Task Start() { if (this.State != ServiceState.Stopped) { throw new InvalidOperationException("Another instance of this service is already executing."); } if (this.Configuration == null) { throw new InvalidOperationException("The service must first be configured by calling LoadConfiguration."); } return(Task.Run( async() => { _stateSubject.OnNext(ServiceState.Starting); // initial setup // see https://stackoverflow.com/questions/2977630/wcf-instance-already-exists-in-counterset-error-when-reopening-servicehost GC.Collect(); GC.WaitForPendingFinalizers(); _localAgents.Clear(); _remoteAgents.Clear(); WcfFactory.BindingListenBacklog = this.Configuration.WcfBindingListenBacklog; WcfFactory.BindingMaxConnections = this.Configuration.WcfBindingMaxConnections; WcfFactory.BehaviorMaxConcurrentCalls = this.Configuration.WcfBehaviorMaxConcurrentCalls; WcfFactory.BehaviorMaxConcurrentSessions = this.Configuration.WcfBehaviorMaxConcurrentSessions; WcfFactory.BehaviorMaxConcurrentInstances = this.Configuration.WcfBehaviorMaxConcurrentInstances; this.MinOperationRetryDelay = TimeSpan.FromMilliseconds(this.Configuration.MinOperationRetryDelayInMs); this.MaxOperationRetryDelay = TimeSpan.FromMilliseconds(this.Configuration.MaxOperationRetryDelayInMs); foreach (var folder in this.Configuration.DependencyFolders) { _dependencyFolders.Add(folder); } // create local peer this.LocalPeerNode = await PeerNode.Create(this.Configuration.Host, this.Configuration.Port, this.Configuration.RxPort, this.Configuration.Description).ConfigureAwait(false); Log.Debug().Message("Adresse assignée au AgentBroker: '{0}'.", this.LocalPeerNode).Write(); _nextRxPort = this.Configuration.RxPort; // peers and agents creation // create local PeerCommunicationAgent var peerAgentInfo = await GetOrRegisterLocalAgent(PeerCommunicationAgent.Configuration, isInternal: true, forceRegister: true).ConfigureAwait(false); // create local agents await Task.WhenAll( this.Configuration.Agents .Where(agentConfig => agentConfig.Enabled) .Select(agentConfig => GetOrRegisterLocalAgent(agentConfig, isInternal: false, forceRegister: true))).ConfigureAwait(false); // activate internal agents await Task.WhenAll(GetLocalAgentInfos <IAgent>().Where(a => a.IsInternal).Select(a => a.Agent.Activate())).ConfigureAwait(false); // get remote peers list var remotePeers = ( await Task.WhenAll( this.Configuration.Peers .Where(p => p.Enabled) .Select(p => PeerNode.Create(p.Host, p.Port, p.RxPort, p.Description))) .ConfigureAwait(false) ).AsEnumerable(); // filter out this multiagent from the configuration's peer list by comparing their IP and port (host is resolved if required) // note that == and != operators are NOT overloaded by IPAddress, the Equals method must be used instead remotePeers = remotePeers .Where(p => p.Port != this.LocalPeerNode.Port || !p.Host.Equals(this.LocalPeerNode.Host)); // create remote peers foreach (var peer in remotePeers) { RegisterPeer(peer); } _heartbeatCts = new CancellationTokenSource(); _heartbeatTask = StartHeartbeat(_heartbeatCts.Token); _stateSubject.OnNext(ServiceState.Started); // activate all local agents if requested // must be done AFTER service state transition to Started because ObserveXXX are active only when the service is started if (this.Configuration.AutoActivateAgents) { await Task.WhenAll(GetLocalAgentInfos <IAgent>().Select(a => a.Agent.Activate())).ConfigureAwait(false); } }) .ContinueWith( async t => { if (t.IsCanceled) { throw (Exception)t.Exception ?? new OperationCanceledException(); } else if (t.IsFaulted) { await Stop(true).ConfigureAwait(false); throw t.Exception; } }) .Unwrap()); }
public void OnHotkeyModeChanged(bool enabled) { _hotkeyModeEnabledSubject.OnNext(enabled); }
private Task <TResult> MakeStateTransition <TResult>(ProviderState startState, ProviderState intermediateState, ProviderState endState, Func <Task <TResult> > action, Func <Task <bool> > before = null, Func <Task> after = null) { if (action == null) { throw new ArgumentNullException("action"); } var originalState = this.State; if (originalState != startState) { throw new InvalidStateTransitionException(string.Format("Current state '{0}' is invalid, it must be '{1}'.", originalState, startState)); } var cts = new CancellationTokenSource(); _currentStateTransitionCts = cts; cts.Token.Register(() => _providerStateSubject.OnNext(originalState)); Func <Task <TResult> > doTransition = async() => { try { Log.Debug().Message("ProviderState intermediate transition: {0}->{1}.", originalState, intermediateState).Write(); _providerStateSubject.OnNext(intermediateState); // if before function call fails, rollback and return immediately if (before != null && !(await before().ConfigureAwait(false))) { _providerStateSubject.OnNext(originalState); return(default(TResult)); } var result = await action().ConfigureAwait(false); if (after != null) { await after().ConfigureAwait(false); } Log.Debug().Message("ProviderState transition successful: {0}->{1}->{2}.", originalState, intermediateState, endState).Write(); _providerStateSubject.OnNext(endState); return(result); } catch { Log.Warn().Message("ProviderState transition failed: {0}->{1}->{2}.", originalState, intermediateState, endState).Write(); _providerStateSubject.OnNext(ProviderState.Failed); throw; } finally { // will also dispose subscriptions to CTS cancellation token cts.Dispose(); } }; var task = doTransition(); _currentStateTransitionTask = task; return(task); }