public void RequestSynchronization(ExtendedNodeInfo nodeInfo, Dictionary<string, int> currentAggregateVersions)
 {
     var req = CreateRequest("RequestSynchronization");
     TCPInternalQueueService.WriteNodeInfo(req, nodeInfo);
     req.Write(currentAggregateVersions.Count);
     foreach (var pair in currentAggregateVersions)
     {
         req.Write(pair.Key);
         req.Write(pair.Value);
     }
     SendReceive(req);
 }
        private void OnSynchronizationFinished(ExtendedNodeInfo nodeInfo, Dictionary<string, int> writtenVersions)
        {
            // todo: wrap this into transaction

            lock (m_SyncRoot)
            {
                try
                {
                    Core.Server.Log.Debug("Sync with {0} almost finished. Switching to readonly mode", nodeInfo.InternalAddress);
                    Core.Server.Configuration.EnterReadonlyMode();
                    try
                    {
                        var syncedNode = ProxyHelper.TranslateNodeInfo(nodeInfo);
                        syncedNode.CreateProxy();
                        syncedNode.Proxy.Open();

                        Core.Server.Log.Debug("Handling last updates...");
                        var currentVersions = AggregateRepository.Instance.GetLastVersions();
                        if (!writtenVersions.AreEqualToVersions(currentVersions))
                            writtenVersions = DoSync(syncedNode.Proxy, currentVersions);

                        Core.Server.Log.Debug("Introducing {0} to everyone, including myself...",
                                              nodeInfo.InternalAddress);
                        foreach (var node in Core.Server.Configuration.Nodes.Siblings)
                            node.Proxy.IntroduceNewNode(nodeInfo);
                        Core.Server.Configuration.Nodes.AddNewNode(syncedNode);

                        Core.Server.Log.Debug("Checking current configuration...");
                        ProxyHelper.EnsureNodesConfigurationIsValid();

                        Core.Server.Log.Debug("Notifying {0} about finish of sync", nodeInfo.InternalAddress);
                        if (!syncedNode.Proxy.NotificateSynchronizationFinished(writtenVersions))
                            throw new ApplicationException(
                                "Synced node version didn't match current version, after all the sync process");

                        Core.Server.Log.Debug("Sync with {0} has finished successfully. Exiting readonly mode", nodeInfo.InternalAddress);
                    }
                    finally
                    {
                        Core.Server.Configuration.ExitReadonlyMode();
                    }
                }
                catch (Exception ex)
                {
                    Core.Server.Log.Error("Error while finishing sync: {0}{1}{0}{2}", Environment.NewLine, ex.Message, ex.StackTrace);
                }
            }
        }
        public void StartBackgroundSync(ExtendedNodeInfo nodeInfo, Dictionary<string, int> aggregateVersions)
        {
            //todo MM: ensure single background task
            Task.Factory.StartNew(() =>
            {
                Dictionary<string, int> writtenVersions = aggregateVersions,
                                        currentVersions = AggregateRepository.Instance.GetLastVersions();

                using(var requester = new SafeInternalQueueServiceProxy(nodeInfo.InternalAddress))
                {
                    requester.Open();
                    while (!writtenVersions.AreEqualToVersions(currentVersions))
                    {
                        writtenVersions = DoSync(requester, aggregateVersions);
                        currentVersions = AggregateRepository.Instance.GetLastVersions();
                    }
                }

                OnSynchronizationFinished(nodeInfo, writtenVersions);
            });
        }
 public void IntroduceNewNode(ExtendedNodeInfo nodeInfo)
 {
     var req = CreateRequest("IntroduceNewNode");
     TCPInternalQueueService.WriteNodeInfo(req, nodeInfo);
     SendReceive(req);
 }