public bool GetRemotePeerStatus(IPAddress ip, int port)
        {
            if (ip == null)
            {
                throw new ArgumentNullException("ip");
            }

            return(GetRemotePeerStatus(PeerNode.Create(ip, port, 0)));
        }
        public bool GetRemotePeerStatus(PeerNode peer)
        {
            if (peer == null)
            {
                throw new ArgumentNullException("peer");
            }

            var peerInfo = GetRemoteAgentInfos <IPeerCommunicationAgent>().FirstOrDefault(info => info.PeerNode == peer);

            return(peerInfo == null ? false : peerInfo.IsReachable);
        }
Exemple #3
0
 public bool Equals(PeerNode other)
 {
     if (other == null)
     {
         return(false);
     }
     else
     {
         return(this.Host == other.Host && this.Port == other.Port);
     }
 }
        public string GetAgentId(PeerNode peer, string agentName)
        {
            if (peer == null)
            {
                throw new ArgumentNullException("peer");
            }
            if (string.IsNullOrEmpty(agentName))
            {
                throw new ArgumentNullException("agentName");
            }

            return(string.Format("{0}:{1} - {2}", peer.Host, peer.Port, agentName));
        }
        private Uri GetAgentUri(PeerNode peer, string agentId)
        {
            if (peer == null)
            {
                throw new ArgumentNullException("peer");
            }
            if (string.IsNullOrEmpty(agentId))
            {
                throw new ArgumentNullException("agentId");
            }

            return(new Uri(string.Format("{0}://{1}:{2}/{3}/", Uri.UriSchemeNetTcp, peer.Host, peer.Port, agentId)));
        }
        internal RemoteAgentInformation(PeerNode peerNode, string agentId, AgentDisplayData displayData, IEnumerable <string> contracts, bool isInternal, ServiceClientFactory serviceClientFactory)
            : base(peerNode, agentId, contracts, isInternal)
        {
            if (displayData == null)
            {
                throw new ArgumentNullException("displayData");
            }
            if (serviceClientFactory == null)
            {
                throw new ArgumentNullException("serviceClientFactory");
            }

            _displayData = displayData;
            this.ServiceClientFactory = serviceClientFactory;
        }
        private void RegisterPeer(PeerNode peer)
        {
            if (peer == null)
            {
                throw new ArgumentNullException("peer");
            }

            var peerAgentId = GetAgentId(peer, PeerCommunicationAgent.Configuration.Name);

            var peerAgentInfo = GetOrRegisterRemoteAgent(
                peer,
                peerAgentId,
                new AgentDisplayData(PeerCommunicationAgent.Configuration.Name, PeerCommunicationAgent.Configuration.ShortName, PeerCommunicationAgent.Configuration.Description),
                new[] { typeof(IPeerCommunicationAgent).AssemblyQualifiedName, typeof(IAgent).AssemblyQualifiedName },
                isInternal: true,
                forceRegister: true);

            // broadcast new peer communication agent, sending connection state immediately to the remote peer
            _agentSubject.OnNext(new SerializableAgentInformation(peerAgentInfo));
        }
Exemple #8
0
        internal LocalAgentInformation(PeerNode peerNode, string agentId, AgentConfiguration configuration, IEnumerable <string> contracts, bool isInternal, IAgent agent, ServiceHost serviceHost)
            : base(peerNode, agentId, contracts, isInternal)
        {
            if (agent == null)
            {
                throw new ArgumentNullException("agent");
            }
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }
            if (serviceHost == null)
            {
                throw new ArgumentNullException("serviceHost");
            }

            this.Configuration = configuration;
            this.Agent         = agent;
            this.ServiceHost   = serviceHost;
        }
        internal AgentInformation(PeerNode peer, string agentId, IEnumerable <string> contracts, bool isInternal)
        {
            if (peer == null)
            {
                throw new ArgumentNullException("peer");
            }
            if (string.IsNullOrEmpty(agentId))
            {
                throw new ArgumentNullException("agentId");
            }
            if (contracts == null)
            {
                throw new ArgumentNullException("contracts");
            }

            this.PeerNode   = peer;
            this.AgentId    = agentId;
            this.Contracts  = contracts.Distinct().ToArray();
            this.IsInternal = isInternal;
        }
        private RemoteAgentInformation GetOrRegisterRemoteAgent(PeerNode peer, string agentId, AgentDisplayData displayData, IEnumerable <string> contracts, bool isInternal, bool forceRegister = false)
        {
            if (peer == null)
            {
                throw new ArgumentNullException("peer");
            }
            if (string.IsNullOrEmpty(agentId))
            {
                throw new ArgumentNullException("agentId");
            }
            if (displayData == null)
            {
                throw new ArgumentNullException("displayData");
            }
            if (contracts == null)
            {
                throw new ArgumentNullException("contracts");
            }

            var newLazyRemote = new Lazy <RemoteAgentInformation>(
                () =>
            {
                var serviceClientFactory = new ServiceClientFactory(GetAgentUri(peer, agentId));
                return(new RemoteAgentInformation(peer, agentId, displayData, contracts, isInternal, serviceClientFactory));
            });

            Lazy <RemoteAgentInformation> lazyRemote;

            if (!forceRegister)
            {
                lazyRemote = _remoteAgents.GetOrAdd(agentId, newLazyRemote);
            }
            else
            {
                lazyRemote = _remoteAgents.AddOrUpdate(agentId, newLazyRemote, (id, old) => newLazyRemote);
            }

            // do not broadcast agent immediately, it will be done on next heartbeat (see StartHeartbeat)

            return(lazyRemote.Value);
        }
        public async Task <bool> GetRemotePeerStatus(string host, int port)
        {
            var peerNode = await PeerNode.Create(host, port, 0).ConfigureAwait(false);

            return(GetRemotePeerStatus(peerNode));
        }
        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());
        }