public void WillSkipSegmentsThatHasItemsInThem()
            {
                var ranges           = Enumerable.Range(0, 500).ToArray();
                var assignedSegments = replication.AssignAllEmptySegments(NodeEndpoint.ForTest(1), ReplicationType.Ownership, ranges);

                Assert.Equal(ranges.Skip(1).ToArray(), assignedSegments);
            }
            public void WillAssignAllSegmentsWeAskForImmediately()
            {
                var ranges           = Enumerable.Range(0, 500).ToArray();
                var assignedSegments = replication.AssignAllEmptySegments(NodeEndpoint.ForTest(1), ReplicationType.Ownership, ranges);

                Assert.Equal(ranges, assignedSegments);
            }
Пример #3
0
        public void CanReplicateSegmentWithDataWhileStillServingRequestForSegment()
        {
            using (var storageProxy = new DistributedHashTableStorageClient(storageHost.Endpoint))
            {
                var topology = new DistributedHashTableMasterClient(masterUri).GetTopology();
                storageProxy.Put(topology.Version, new ExtendedPutRequest
                {
                    Bytes   = new byte[] { 1, 2, 3 },
                    Key     = "test",
                    Segment = 1,
                });

                var result = storageProxy.ReplicateNextPage(NodeEndpoint.ForTest(13), ReplicationType.Ownership, 1);
                Assert.Equal("test", result.PutRequests[0].Key);

                storageProxy.Put(topology.Version, new ExtendedPutRequest
                {
                    Bytes   = new byte[] { 1, 2, 3 },
                    Key     = "test2",
                    Segment = 1,
                });

                result = storageProxy.ReplicateNextPage(NodeEndpoint.ForTest(13), ReplicationType.Ownership, 1);
                Assert.Equal("test2", result.PutRequests[0].Key);
            }
        }
Пример #4
0
            public void AfterBackupsCompleteWillStartReplicationAgain()
            {
                node.Storage.Stub(x => x.Get(0)).IgnoreArguments().Return(new Value[0][]);

                OnlineSegmentReplicationCommand command = null;

                executer.Stub(x => x.RegisterForExecution(Arg <OnlineSegmentReplicationCommand> .Is.TypeOf))
                .WhenCalled(invocation => command = (OnlineSegmentReplicationCommand)invocation.Arguments[0]);

                node.SetTopology(new Topology(new[]
                {
                    new Segment
                    {
                        AssignedEndpoint = NodeEndpoint.ForTest(91),
                        PendingBackups   = { endPoint }
                    },
                }, 1));

                command.RaiseCompleted();

                node.SetTopology(new Topology(new[]
                {
                    new Segment
                    {
                        AssignedEndpoint = NodeEndpoint.ForTest(91),
                        PendingBackups   = { endPoint }
                    },
                }, 2));

                executer.AssertWasCalled(
                    x => x.RegisterForExecution(Arg <OnlineSegmentReplicationCommand> .Is.TypeOf),
                    o => o.Repeat.Twice());
            }
Пример #5
0
            public void CanGiveUpOnSegment()
            {
                var existingEndpoint = new NodeEndpoint
                {
                    Async = new Uri("rhino.queues://other:2202/replication"),
                    Sync  = new Uri("rhino.dht://other:2201")
                };

                masterProxy.Join(existingEndpoint);

                var newEndpoint = new NodeEndpoint
                {
                    Async = new Uri("rhino.queues://localhost:2202/replication"),
                    Sync  = new Uri("rhino.dht://localhost:2201")
                };

                var segments = masterProxy.Join(newEndpoint);

                masterProxy.GaveUp(newEndpoint, ReplicationType.Ownership, segments[0].Index, segments[1].Index);

                var topology = masterProxy.GetTopology();

                Assert.Equal(existingEndpoint, topology.Segments[segments[0].Index].AssignedEndpoint);
                Assert.Equal(existingEndpoint, topology.Segments[segments[1].Index].AssignedEndpoint);

                Assert.Null(topology.Segments[segments[0].Index].InProcessOfMovingToEndpoint);
                Assert.Null(topology.Segments[segments[1].Index].InProcessOfMovingToEndpoint);
            }
        public int[] AssignAllEmptySegments(NodeEndpoint replicationEndpoint,
                                            ReplicationType type,
                                            int[] segments)
        {
            var reservedSegments = new List <int>();

            hashTable.Batch(actions =>
            {
                foreach (var segment in segments)
                {
                    if (actions.HasTag(segment))
                    {
                        continue;
                    }
                    if (type == ReplicationType.Ownership &&
                        MarkSegmentAsAssignedToEndpoint(actions, replicationEndpoint, segment) == false)
                    {
                        continue;
                    }
                    reservedSegments.Add(segment);
                }
                actions.Commit();
            });

            return(reservedSegments.ToArray());
        }
Пример #7
0
        public IDistributedHashTableStorage Create(NodeEndpoint endpoint)
        {
            PooledDistributedHashTableStorageClientConnection storage = null;

            lock (locker)
            {
                LinkedList <PooledDistributedHashTableStorageClientConnection> value;
                if (pooledConnections.TryGetValue(endpoint, out value) && value.Count > 0)
                {
                    storage = value.First.Value;
                    value.RemoveFirst();
                }
            }
            if (storage != null)
            {
                if (storage.Connected == false)
                {
                    log.DebugFormat("Found unconnected connection in the pool for {0}", endpoint.Sync);
                    try
                    {
                        storage.Dispose();
                    }
                    catch (Exception e)
                    {
                        log.Debug("Error when disposing unconnected connection in the pool", e);
                    }
                }
                else
                {
                    return(storage);
                }
            }
            log.DebugFormat("Creating new connection in the pool to {0}", endpoint.Sync);
            return(new PooledDistributedHashTableStorageClientConnection(this, endpoint));
        }
Пример #8
0
            public void WillNotStartReplicationIfCurrentlyReplicatingBackups()
            {
                node.Storage.Stub(x => x.Get(0)).IgnoreArguments().Return(new Value[0][]);

                node.SetTopology(new Topology(new[]
                {
                    new Segment
                    {
                        AssignedEndpoint = NodeEndpoint.ForTest(91),
                        PendingBackups   = { endPoint }
                    },
                }, 1));

                node.SetTopology(new Topology(new[]
                {
                    new Segment
                    {
                        AssignedEndpoint = NodeEndpoint.ForTest(91),
                        PendingBackups   = { endPoint }
                    },
                }, 2));

                executer.AssertWasCalled(
                    x => x.RegisterForExecution(Arg <OnlineSegmentReplicationCommand> .Is.TypeOf),
                    o => o.Repeat.Once());
            }
Пример #9
0
 private bool[] GetRemovesResults(NodeEndpoint endpoint,
                                  ExtendedRemoveRequest[] removeRequests,
                                  int backupIndex)
 {
     try
     {
         using (var client = pool.Create(endpoint))
         {
             return(client.Remove(topology.Version, removeRequests));
         }
     }
     catch (SeeOtherException soe)
     {
         return(GetRemovesResults(soe.Endpoint, removeRequests, backupIndex));
     }
     catch (TopologyVersionDoesNotMatchException)
     {
         RefreshTopology();
         return(RemoveInternal(removeRequests, backupIndex));
     }
     catch (Exception)
     {
         try
         {
             return(RemoveInternal(removeRequests, backupIndex + 1));
         }
         catch (NoMoreBackupsException)
         {
         }
         throw;
     }
 }
Пример #10
0
 private PutResult[] GetPutsResults(NodeEndpoint endpoint,
                                    ExtendedPutRequest[] putRequests,
                                    int backupIndex)
 {
     try
     {
         using (var client = pool.Create(endpoint))
         {
             return(client.Put(topology.Version, putRequests));
         }
     }
     catch (SeeOtherException soe)
     {
         return(GetPutsResults(soe.Endpoint, putRequests, backupIndex));
     }
     catch (TopologyVersionDoesNotMatchException)
     {
         RefreshTopology();
         return(PutInternal(putRequests, backupIndex));
     }
     catch (Exception)
     {
         try
         {
             return(PutInternal(putRequests, backupIndex + 1));
         }
         catch (NoMoreBackupsException)
         {
         }
         throw;
     }
 }
            public void WillGiveExistingKeysFromSegment()
            {
                var result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);

                Assert.Equal(1, result.PutRequests.Length);
                Assert.Equal(new byte[] { 1 }, result.PutRequests[0].Bytes);
            }
Пример #12
0
 public OnGaveUp()
 {
     master = new DistributedHashTableMaster();
     master.CaughtUp(NodeEndpoint.ForTest(9),
                     ReplicationType.Ownership,
                     master.Join(NodeEndpoint.ForTest(9)).Select(x => x.Index).ToArray());
     endPoint = NodeEndpoint.ForTest(5);
 }
Пример #13
0
            public void AddingNewNodeResultInAllSegmentsHavingAtLeastTwoBackupCopy()
            {
                var yetAnotherEndPoint = NodeEndpoint.ForTest(7);
                var ranges             = master.Join(yetAnotherEndPoint);

                master.CaughtUp(yetAnotherEndPoint, ReplicationType.Ownership, ranges.Select(x => x.Index).ToArray());
                Assert.True(master.Segments.All(x => x.PendingBackups.Count >= 2));
            }
Пример #14
0
 public HandlingAssignedSegments()
 {
     master   = MockRepository.GenerateStub <IDistributedHashTableMaster>();
     executer = MockRepository.GenerateStub <IExecuter>();
     endPoint = NodeEndpoint.ForTest(1);
     node     = new DistributedHashTableNode(master, executer, new BinaryMessageSerializer(), endPoint, MockRepository.GenerateStub <IQueueManager>(),
                                             MockRepository.GenerateStub <IDistributedHashTableNodeReplicationFactory>());
 }
Пример #15
0
            public void DirectlyModifyingTopologyAndThenCallingRefreshEndpointsShouldShowAllEndpoints()
            {
                Assert.False(master.Endpoints.Any(x => x == NodeEndpoint.ForTest(1)));

                master.Topology.Segments[0].AssignedEndpoint = NodeEndpoint.ForTest(1);
                master.RefreshEndpoints();

                Assert.True(master.Endpoints.Any(x => x == NodeEndpoint.ForTest(1)));
            }
            public void WillRememberKeysSentDuringPreviousReplication()
            {
                var result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);

                Assert.Equal(1, result.PutRequests.Length);

                result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);
                Assert.Equal(0, result.PutRequests.Length);
            }
Пример #17
0
            public OnMasterWithOneExistingNode()
            {
                master   = new DistributedHashTableMaster();
                endPoint = NodeEndpoint.ForTest(9);

                var existingEndpoint = NodeEndpoint.ForTest(3);
                var ranges           = master.Join(existingEndpoint);

                master.CaughtUp(existingEndpoint, ReplicationType.Ownership, ranges.Select(x => x.Index).ToArray());
            }
Пример #18
0
 public WhenFinishedReplicatingSegment()
 {
     master   = MockRepository.GenerateStub <IDistributedHashTableMaster>();
     executer = MockRepository.GenerateStub <IExecuter>();
     endPoint = NodeEndpoint.ForTest(1);
     master.Stub(x => x.Join(Arg.Is(endPoint)))
     .Return(new Segment[0]);
     node = new DistributedHashTableNode(master, executer, new BinaryMessageSerializer(), endPoint, MockRepository.GenerateStub <IQueueManager>(),
                                         MockRepository.GenerateStub <IDistributedHashTableNodeReplicationFactory>());
 }
Пример #19
0
        public void CanReplicateEmptySegments()
        {
            using (var storageProxy = new DistributedHashTableStorageClient(storageHost.Endpoint))
            {
                var segments = new[] { 1, 2, 3 };

                var assignedSegments = storageProxy.AssignAllEmptySegments(NodeEndpoint.ForTest(13), ReplicationType.Ownership, segments);

                Assert.Equal(segments, assignedSegments);
            }
        }
Пример #20
0
            public void CanJoinToMaster()
            {
                var endpoint = new NodeEndpoint
                {
                    Async = new Uri("rhino.queues://localhost:2202/replication"),
                    Sync  = new Uri("rhino.dht://localhost:2201")
                };
                var segments = masterProxy.Join(endpoint);

                Assert.Equal(Constants.NumberOfSegments, segments.Length);
                Assert.True(segments.All(x => x.AssignedEndpoint.Equals(endpoint)));
            }
 public OnlineSegmentReplicationCommand(
     NodeEndpoint endpoint,
     Segment[] segments,
     ReplicationType type,
     IDistributedHashTableNode node,
     IDistributedHashTableNodeReplicationFactory factory)
 {
     this.endpoint = endpoint;
     this.segments = segments;
     this.type     = type;
     this.node     = node;
     this.factory  = factory;
 }
Пример #22
0
            public void TopologyContainsPendingBackupsForCurrentNodeWillStartsBackupReplication()
            {
                node.SetTopology(new Topology(new[]
                {
                    new Segment
                    {
                        AssignedEndpoint = NodeEndpoint.ForTest(91),
                        PendingBackups   = { endPoint }
                    },
                }, 1));

                executer.AssertWasCalled(x => x.RegisterForExecution(Arg <OnlineSegmentReplicationCommand> .Is.TypeOf));
            }
        private static bool MarkSegmentAsAssignedToEndpoint(PersistentHashTableActions actions,
                                                            NodeEndpoint endpoint,
                                                            int segment)
        {
            var result = actions.Put(new PutRequest
            {
                Key = Constants.MovedSegment + segment,
                OptimisticConcurrency = true,
                Bytes = endpoint.ToBytes(),
            });

            return(result.ConflictExists == false);
        }
            public void RemovingKeyInSegmentAsisgnedElsewhereShouldThrow()
            {
                var ranges = Enumerable.Range(0, 500).ToArray();

                replication.AssignAllEmptySegments(NodeEndpoint.ForTest(1), ReplicationType.Ownership, ranges);
                var exception = Assert.Throws <SeeOtherException>(() => node.Storage.Remove(topologyVersion, new ExtendedRemoveRequest
                {
                    Key     = "test",
                    Segment = 0,
                }));

                Assert.Equal(NodeEndpoint.ForTest(1), exception.Endpoint);
            }
Пример #25
0
            public void WillRegisterSegmentsNotAssignedToMeForReplication()
            {
                master.Stub(x => x.Join(Arg.Is(endPoint)))
                .Return(new[]
                {
                    new Segment {
                        AssignedEndpoint = NodeEndpoint.ForTest(9)
                    },
                });

                node.Start();

                executer.AssertWasCalled(x => x.RegisterForExecution(Arg <OnlineSegmentReplicationCommand> .Is.TypeOf));
            }
Пример #26
0
            public void WhenNoSegmentIsAssignedToNodeStateWillBeStarting()
            {
                master.Stub(x => x.Join(Arg.Is(endPoint)))
                .Return(new[]
                {
                    new Segment {
                        AssignedEndpoint = NodeEndpoint.ForTest(9)
                    },
                });

                node.Start();

                Assert.Equal(NodeState.Starting, node.State);
            }
            public void WhenItemIsRemovedWillResultInRemovalRequestOnNextReplicationPage()
            {
                var result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);

                Assert.Equal(1, result.PutRequests.Length);
                node.Storage.Remove(node.GetTopologyVersion(), new ExtendedRemoveRequest
                {
                    Key             = "test",
                    SpecificVersion = putResult.Version,
                    Segment         = 0,
                });

                result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);
                Assert.Equal(1, result.RemoveRequests.Length);
            }
            public void WhenDoneGettingAllKeysWillAssignSegmentToEndpoint()
            {
                var result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);

                Assert.Equal(1, result.PutRequests.Length);

                result = replication.ReplicateNextPage(NodeEndpoint.ForTest(1), ReplicationType.Ownership, 0);
                Assert.Equal(0, result.PutRequests.Length);

                var exception = Assert.Throws <SeeOtherException>(() => node.Storage.Remove(topologyVersion, new ExtendedRemoveRequest
                {
                    Key     = "test",
                    Segment = 0,
                }));

                Assert.Equal(NodeEndpoint.ForTest(1), exception.Endpoint);
            }
Пример #29
0
        public void WhenFinishedReplicatingWillTellTheReplicatorSo()
        {
            using (var storageProxy = new DistributedHashTableStorageClient(storageHost.Endpoint))
            {
                var topology = new DistributedHashTableMasterClient(masterUri).GetTopology();
                storageProxy.Put(topology.Version, new ExtendedPutRequest
                {
                    Bytes   = new byte[] { 1, 2, 3 },
                    Key     = "test",
                    Segment = 1,
                });

                var result = storageProxy.ReplicateNextPage(NodeEndpoint.ForTest(13), ReplicationType.Ownership, 1);
                Assert.Equal("test", result.PutRequests[0].Key);

                result = storageProxy.ReplicateNextPage(NodeEndpoint.ForTest(13), ReplicationType.Ownership, 1);
                Assert.True(result.Done);
            }
        }
Пример #30
0
        public void WhenReplicatingEmptySegmentsWillNotReplicateSegmentsThatHasValues()
        {
            using (var storageProxy = new DistributedHashTableStorageClient(storageHost.Endpoint))
            {
                var topology = new DistributedHashTableMasterClient(masterUri).GetTopology();
                storageProxy.Put(topology.Version, new ExtendedPutRequest
                {
                    Bytes   = new byte[] { 1, 2, 3 },
                    Key     = "test",
                    Segment = 1,
                });

                var segments = new[] { 1, 2, 3 };

                var assignedSegments = storageProxy.AssignAllEmptySegments(NodeEndpoint.ForTest(13), ReplicationType.Ownership, segments);

                Assert.Equal(new[] { 2, 3 }, assignedSegments);
            }
        }