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; }
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); } } }
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(); }
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(); }