public static ServiceDescription GetRandomServiceDescription(IOverlayNode ownerNode, Random rnd) { var srvName = Guid.NewGuid().ToString() + "_node_" + ownerNode.Id; return new ServiceDescription { Name = srvName, OwnerNode = ownerNode, Data = GetRandomServiceDescriptionData(ownerNode, srvName, rnd) }; }
public static OverlayData[] GetRandomServiceDescriptionData(IOverlayNode ownerNode, string serviceName, Random rnd) { var result = new List<OverlayData>(); var itemsCnt = rnd.Next(2, 5); for (var i = 0; i < itemsCnt; ++i) { result.Add(new OverlayData { OwnerNode = ownerNode, ServiceName = serviceName, AttrValue = new KeyValuePair<string,object>( GetRandomAlphanumericString(rnd), GetRandomAlphanumericString(rnd) ) }); } return result.ToArray(); }
private bool IsNodeFailed(IOverlayNode testNode) { if (FailedNodes.Any(n => n == testNode.Id)) { var chnl = CommunicationMgr.GetChannel(testNode); try { chnl.Service.Ping(); } catch (Exception) { Log.Write(LogEvent.Debug, "IsNodeFailed check for node {0} returned true", testNode); return true; } // remove from failed if the check was ok Log.Write(LogEvent.Debug, "IsNodeFailed check for node {0} returned false, removing the node from failed ones", testNode); FailedNodes.Remove(testNode.Id); return false; } Log.Write(LogEvent.Debug, "IsNodeFailed check for node {0} returned false since there is no such node in the list", testNode); return false; }
public void Bind(IOverlayNode node) { LocalNode = (LocalNode)node; LocalNode.Params = Params; LocalNode.InitFingerTable(); LocalNode.InitSuccessorCache(); MaintenanceSrv = new MaintenanceService(this) { AfterFixFingersWaitInterval = Params.AfterFixFingersWaitInterval, AfterStabilizeSuccCacheWaitInterval = Params.AfterStabilizeSuccCacheWaitInterval, AfterStabilizeWaitInterval = Params.AfterStabilizeWaitInterval }; RunMessageProcessor(); }
public FindKeySuccessorResult(IOverlayNode result, bool returnSuccessorAsResult) { Node = result; ReturnSuccessorAsResult = returnSuccessorAsResult; StatsCollector = new StatisticsCollector(); }
public void SetPredecessor(IOverlayNode candidateNode) { Log.Write(LogEvent.Debug, "Calling set predecessor for node {0} with candidate {1}", LocalNode, candidateNode); // ensure that we have exclusive access to predecessor node // not using 'lock' shortcut here because predecessor can be null bool predecessorLockTaken = false; try { Monitor.Enter(LocalNode.PredecessorLock, ref predecessorLockTaken); LocalNode.Predecessor = candidateNode; Log.Write(LogEvent.Debug, "Set predecessor for node {0} with candidate {1}", LocalNode, candidateNode); } finally { if (predecessorLockTaken) { Monitor.Exit(LocalNode.PredecessorLock); } } }
private void Rejoin(IOverlayNode localInitEndpoint) { try { if (Join(localInitEndpoint)) { return; } } catch (Exception ex) { Log.Write(LogEvent.Warn, "Cannot rejoin with cached initial node {0}, see error details: \r\n {1}", localInitEndpoint, ex); } var possibleRejoinInitNodes = LocalNode.Fingers.Select(f => f.Node) .Union(LocalNode.SuccessorCache) .Union(new[] { LocalNode.Predecessor }) .Where(n => n != null && n != LocalNode) .Distinct().ToArray(); foreach (var n in possibleRejoinInitNodes) { try { if (Join(n)) { return; } } catch (Exception ex) { Log.Write(LogEvent.Warn, "Cannot rejoin with node {0} as initial, continue trying, see error details: \r\n {1}", localInitEndpoint, ex); } } }
public void FixSeedNode(IOverlayNode joinedNode) { lock (LocalNode.SuccessorLock) { if (LocalNode.Successor.Equals(LocalNode)) { // its not correct because there is at least one more node in the network (which called this method) LocalNode.Successor = joinedNode; } } }
public bool Join(IOverlayNode initNode = null) { if (LocalNode.State == NodeState.Connected) { Log.Write(LogEvent.Warn, "Node {0} cannot join the network because it is aleady marked as joined", LocalNode); return false; } if (initNode != null) { LocalNode.InitNode = initNode; if (initNode.Equals(LocalNode)) { Log.Write(LogEvent.Warn, "Bootstrapper node {0} cannot be the same as the local node {1}", initNode, LocalNode); return false; } else { Log.Write(LogEvent.Info, "Joining the ring with node {0}, bootstrapper node {1}, ring length {2}", LocalNode, initNode, Params.RingLength); try { CommunicationMgr.Start(this, LocalNode); } catch (Exception ex) { Log.Write(LogEvent.Error, "Cannot start local service for node {0}. Error details: \r\n {1}", LocalNode, ex); return false; } StartOverlayStateService(); var initNodeChannel = CommunicationMgr.GetChannel(initNode); try { var nodeSuccessor = initNodeChannel.Service.FindKeySuccessor(new FindKeySuccessorArg(LocalNode.Id, true)); // set my own successor LocalNode.Successor = nodeSuccessor.Node; } catch (Exception ex) { if (initNodeChannel.IsUnavailable) { Log.Write(LogEvent.Warn, "Service for node {0} is unavailable, please retry or rejoin with another seed. Error details: \r\n {1}", initNode, ex.ToString()); Leave(); return false; } else { throw; } } // try fixing the successor of the seed node try { initNodeChannel.Service.FixSeedNode(LocalNode); // joined successfully Log.Write(LogEvent.Info, "Joined the ring with node {0}, bootstrapper node {1}, ring length {2}", LocalNode, initNode, Params.RingLength); } catch (Exception ex) { if (initNodeChannel.IsUnavailable) { Log.Write(LogEvent.Warn, "Service for node {0} is unavailable, please retry or rejoin with another seed. Error details: \r\n {1}", initNode, ex.ToString()); Leave(); return false; } else { throw; } } } } else { // start new ring Log.Write(LogEvent.Info, "Starting new ring with node {0}, ring length {1}", LocalNode, Params.RingLength); try { CommunicationMgr.Start(this, LocalNode); } catch (Exception ex) { Log.Write(LogEvent.Error, "Cannot start local service for node {0}. Error details: \r\n {1}", LocalNode, ex.ToString()); return false; } StartOverlayStateService(); Log.Write(LogEvent.Info, "Started new ring with node {0}, ring length {1}", LocalNode, Params.RingLength); } LocalNode.State = NodeState.Connected; // notify that we have successfully joined SendMessage(new OverlayNodeServiceMessage { MsgType = OverlayNodeServiceMessage.MessageType.JoinedSuccessfully }); return true; }
public void FixPredecessor(IOverlayNode candidateNode) { Log.Write(LogEvent.Debug, "Calling fix predecessor for node {0} with candidate {1}", LocalNode, candidateNode); // ensure that we have exclusive access to predecessor node // not using 'lock' shortcut here because predecessor can be null bool predecessorLockTaken = false; try { Monitor.Enter(LocalNode.PredecessorLock, ref predecessorLockTaken); if (LocalNode.Predecessor == null || LocalNode.Predecessor.Equals(LocalNode) || ChordOverlayHelper.IsInCircularInterval(candidateNode.Id, LocalNode.Predecessor.Id, LocalNode.Id)) { LocalNode.Predecessor = candidateNode; Log.Write(LogEvent.Debug, "Fixed predecessor for node {0} with candidate {1}", LocalNode, candidateNode); } } finally { if (predecessorLockTaken) { Monitor.Exit(LocalNode.PredecessorLock); } } }
public void Start(IOverlayNode node) { if (Params.InfoSendInterval == 0) { return; } if (State != InnerState.Started) { Log.Write(LogEvent.Info, "Starting..."); Srv = OverlayStateSrvConnector.Connect(); Cancellation = new CancellationTokenSource(); RunningTask = TaskFactory.StartNew( () => { Log.Write(LogEvent.Info, "Started"); State = InnerState.Started; while (!Cancellation.IsCancellationRequested) { try { var nodePrep = node.PrepareForSerialization(); Srv.Send(new OverlayStateInfo { Data = new Dictionary<string, object> { { "json", Serializer.Serialize(nodePrep) }, { "node_id", nodePrep.Id } }, Kind = OverlayStateInfo.InfoKind.NodeInfo }); } catch (Exception ex) { Log.Write(LogEvent.Warn, "Could send node info to the state service: \r\n" + ex.ToString()); Cancellation.Cancel(); Stop(); } Thread.Sleep(TimeSpan.FromMilliseconds(Params.InfoSendInterval)); } }); } }
public bool Join(IOverlayNode initNode = null) { return RealOverlay.Join(initNode); }
public void Bind(IOverlayNode node) { RealOverlay.Bind(node); }
public VmOverlayNode(IOverlayNode node, Vm vm) : this(node.IpAddress, node.Port, node.OverlayLevel, node.Id, vm) { }