예제 #1
0
        public DistributedHashTable(
            string database,
            Uri url,
            IEndpointRouter endpointRouter,
            IServiceBus bus,
            Node metadata)
        {
            Url = url;
            this.endpointRouter = endpointRouter;
            this.bus = bus;
            Metadata = metadata;

            if (Metadata != null) // sole node in the network, probably
            {
                Metadata.ExecuteSync(uri =>
                {
                    ServiceUtil.Execute<IDistributedHashTableMetaDataProvider>(uri, srv =>
                    {
                        failOver = srv.GetNodeByUri(url);
                    });
                });
            }
            try
            {
                hashTable = new PersistentHashTable(database);
                hashTable.Initialize();
            }
            catch (Exception)
            {
                hashTable.Dispose();
                throw;
            }
        }
 public DistributedHashTableClient(Node metadata)
 {
     metadata.ExecuteSync(uri =>
     {
         ServiceUtil.Execute<IDistributedHashTableMetaDataProvider>(uri, provider =>
         {
             Nodes = provider.GetNetworkNodes();
         });
     });
 }
        public DistributedHashTableMetaDataProvider(Network network, Uri url)
        {
            nodes = new Node[network.Nodes.Length];

            for (int i = 0; i < network.Nodes.Length; i++)
            {
                var node = network.Nodes[i];
                if (string.IsNullOrEmpty(node.Name))
                    throw new ArgumentException("Node name cannot be empty. Node #" + i);
                nodes[i] = new Node
                {
                    Name = node.Name,
                    Primary = GetNode(network.Nodes, node.Name),
                    Secondary = GetNode(network.Nodes, node.Secondary),
                    Tertiary = GetNode(network.Nodes, node.Tertiary),
                };
            }

            Url = url;
        }
예제 #4
0
        private void HandleReplication(
            Node originalDestination,
            object valueToSend)
        {
            //if this is the replication node, this is a replicated value,
            // and we don't need to do anything with replication
            if (originalDestination == Replication.Node)
                return;

            // we replicate to our failover nodes
            if (originalDestination.Primary.Sync == Url)
                SendToFailoverNodes(valueToSend);
            else// if this got to us because of fail over
            {
                var primaryEndpoint = endpointRouter.GetRoutedEndpoint(originalDestination.Primary.Async);
                bus.Send(primaryEndpoint, valueToSend);
                var otherNode = originalDestination.GetOtherReplicationNode(Url);
                if(otherNode!=null)
                {
                    var endpoint = endpointRouter.GetRoutedEndpoint(otherNode.Async);
                    bus.Send(endpoint, valueToSend);
                }
            }
        }
예제 #5
0
        public bool[] Remove(Node originalDestination, params RemoveRequest[] valuesToRemove)
        {
            var results = new List<bool>();
            using (var tx = new TransactionScope())
            {
                hashTable.Batch(actions =>
                {
                    foreach (var request in valuesToRemove)
                    {
                        if (request.ParentVersions == null)
                            throw new ArgumentException("Could not accept request with no ParentVersions");

                        var remove = actions.Remove(request);
                        results.Add(remove);
                    }

                    HandleReplication(originalDestination, new RemoveRequests {Requests = valuesToRemove});
                    actions.Commit();
                });

                tx.Complete();
            }
            return results.ToArray();
        }
예제 #6
0
        public PutResult[] Put(Node originalDestination, params PutRequest[] valuesToAdd)
        {
            var results = new List<PutResult>();
            using (var tx = new TransactionScope())
            {
                hashTable.Batch(actions =>
                {
                    foreach (var request in valuesToAdd)
                    {
                        if(request.ParentVersions==null)
                            throw new ArgumentException("Could not accept request with no ParentVersions");
                        if (request.Key.StartsWith(rhinoDhtStartToken))
                            throw new ArgumentException(rhinoDhtStartToken + " is a reserved key prefix");
                        var put = actions.Put(request);
                        //prepare the value for replication
                        request.ReplicationVersion = put.Version;
                        results.Add(put);
                    }

                    HandleReplication(originalDestination, new PutRequests {Requests = valuesToAdd});

                    actions.Commit();
                });

                tx.Complete();
            }
            return results.ToArray();
        }