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]);
     }
 }
예제 #3
0
        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);
 }
예제 #6
0
        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);
        }