public Task <GetManyResult> GetManyAsync(
            Guid clientGuid,
            string domain,
            FactTreeMemento tree,
            Dictionary <long, long> pivotIds,
            int timeoutSeconds)
        {
            GetManyResult result = GetManyInternal(clientGuid, domain, tree, pivotIds);

            if (timeoutSeconds > 0 && !result.Tree.Facts.Any())
            {
                CancellationTokenSource cancellation = new CancellationTokenSource();
                int session = _messageBus.Register(
                    domain,
                    result.LocalPivotIds,
                    clientGuid,
                    () => cancellation.Cancel());
                return(Task
                       .Delay(timeoutSeconds * 1000, cancellation.Token)
                       .ContinueWith(t => t.IsCanceled
                        ? GetManyInternal(clientGuid, domain, tree, pivotIds)
                        : result)
                       .ContinueWith(t =>
                {
                    _messageBus.Unregister(session);
                    cancellation.Dispose();
                    return t.Result;
                }));
            }

            return(Task.FromResult(result));
        }
        private GetManyResult GetManyInternal(Guid clientGuid, string domain, FactTreeMemento tree, Dictionary <long, long> pivotIds)
        {
            var                         localPivotIds     = new List <FactID>();
            FactTreeMemento             messageBody       = new FactTreeMemento(0);
            Dictionary <FactID, FactID> localIdByRemoteId = ForEachFact(tree, fact =>
                                                                        _repository.Save(domain, fact, clientGuid));
            Dictionary <long, long> newPivotIds = new Dictionary <long, long>();

            foreach (var pivot in pivotIds)
            {
                long        remotePivotId = pivot.Key;
                FactID      localPivotId;
                long        pivotValue = pivot.Value;
                TimestampID timestamp  = new TimestampID(0, pivotValue);
                if (localIdByRemoteId.TryGetValue(new FactID {
                    key = remotePivotId
                }, out localPivotId))
                {
                    List <FactID> recentMessages = _repository.LoadRecentMessages(domain, localPivotId, clientGuid, timestamp);
                    foreach (FactID recentMessage in recentMessages)
                    {
                        AddToFactTree(domain, messageBody, recentMessage, localIdByRemoteId);
                        if (recentMessage.key > pivotValue)
                        {
                            pivotValue = recentMessage.key;
                        }
                    }
                    newPivotIds[remotePivotId] = pivotValue;
                    localPivotIds.Add(localPivotId);
                }
            }
            foreach (var pivot in newPivotIds)
            {
                pivotIds[pivot.Key] = pivot.Value;
            }
            var result = new GetManyResult()
            {
                Tree          = messageBody,
                PivotIds      = pivotIds,
                LocalPivotIds = localPivotIds
            };

            return(result);
        }
 private GetManyResult GetManyInternal(Guid clientGuid, string domain, FactTreeMemento tree, Dictionary<long, long> pivotIds)
 {
     var localPivotIds = new List<FactID>();
     FactTreeMemento messageBody = new FactTreeMemento(0);
     Dictionary<FactID, FactID> localIdByRemoteId = ForEachFact(tree, fact =>
         _repository.Save(domain, fact, clientGuid));
     Dictionary<long, long> newPivotIds = new Dictionary<long, long>();
     foreach (var pivot in pivotIds)
     {
         long remotePivotId = pivot.Key;
         FactID localPivotId;
         long pivotValue = pivot.Value;
         TimestampID timestamp = new TimestampID(0, pivotValue);
         if (localIdByRemoteId.TryGetValue(new FactID { key = remotePivotId }, out localPivotId))
         {
             List<FactID> recentMessages = _repository.LoadRecentMessages(domain, localPivotId, clientGuid, timestamp);
             foreach (FactID recentMessage in recentMessages)
             {
                 AddToFactTree(domain, messageBody, recentMessage, localIdByRemoteId);
                 if (recentMessage.key > pivotValue)
                     pivotValue = recentMessage.key;
             }
             newPivotIds[remotePivotId] = pivotValue;
             localPivotIds.Add(localPivotId);
         }
     }
     foreach (var pivot in newPivotIds)
         pivotIds[pivot.Key] = pivot.Value;
     var result = new GetManyResult()
     {
         Tree = messageBody,
         PivotIds = pivotIds,
         LocalPivotIds = localPivotIds
     };
     return result;
 }