internal void StartConnecting() { if (_disconnect.IsCancellationRequested) { return; } if (ConnectedNodes.Count >= MaximumNodeConnection) { return; } if (_connecting) { return; } Task.Factory.StartNew(() => { if (Monitor.TryEnter(_cs)) { _connecting = true; TraceCorrelationScope scope = null; try { while (!_disconnect.IsCancellationRequested && ConnectedNodes.Count < MaximumNodeConnection) { scope = scope ?? _trace.Open(); NodeServerTrace.Information("Connected nodes : " + ConnectedNodes.Count + "/" + MaximumNodeConnection); var parameters = NodeConnectionParameters.Clone(); parameters.TemplateBehaviors.Add(new NodesGroupBehavior(this)); parameters.ConnectCancellation = _disconnect.Token; var addrman = AddressManagerBehavior.GetAddrman(parameters); if (addrman == null) { addrman = _defaultAddressManager; AddressManagerBehavior.SetAddrman(parameters, addrman); } Node node = null; try { var groupSelector = CustomGroupSelector ?? (AllowSameGroup ? WellKnownGroupSelectors.ByRandom : null); node = Node.Connect(_network, parameters, ConnectedNodes.Select(n => n.RemoteSocketEndpoint).ToArray(), groupSelector); var timeout = CancellationTokenSource.CreateLinkedTokenSource(_disconnect.Token); timeout.CancelAfter(5000); node.VersionHandshake(Requirements, timeout.Token); NodeServerTrace.Information("Node successfully connected to and handshaked"); } catch (OperationCanceledException ex) { if (_disconnect.Token.IsCancellationRequested) { break; } NodeServerTrace.Error("Timeout for picked node", ex); if (node != null) { node.DisconnectAsync("Handshake timeout", ex); } } catch (Exception ex) { NodeServerTrace.Error("Error while connecting to node", ex); if (node != null) { node.DisconnectAsync("Error while connecting", ex); } } } } finally { Monitor.Exit(_cs); _connecting = false; if (scope != null) { scope.Dispose(); } } } }, TaskCreationOptions.LongRunning); }
public override string ToString() { var join = string.Join(",", ConnectedNodes.Select(node => node.ToString()).ToArray()); return($"[{join}]"); }