public bool Put(MemBlock key, MemBlock value, int ttl, bool unique, object rs) {
if(value.Length > MAX_BYTES) {
throw new Exception(String.Format(
"Dht only supports storing data smaller than {0} bytes.", MAX_BYTES));
}
PutHandler(key, value, ttl, unique);
Channel remote_put = new Channel();
remote_put.CloseAfterEnqueue();
remote_put.CloseEvent += delegate(Object o, EventArgs eargs) {
object result = false;
try {
result = remote_put.Dequeue();
RpcResult rpcResult = (RpcResult) result;
result = rpcResult.Result;
if(result.GetType() != typeof(bool)) {
throw new Exception("Incompatible return value.");
}
else if(!(bool) result) {
throw new Exception("Unknown error!");
}
}
catch (Exception e) {
lock(_sync) {
_data.RemoveEntry(key, value);
}
result = new AdrException(-32602, e);
}
_rpc.SendResult(rs, result);
};
try {
Address key_address = new AHAddress(key);
ISender s = null;
var structs =
_node.ConnectionTable.GetConnections(ConnectionType.Structured);
// We need to forward this to the appropriate node!
if(((AHAddress)_node.Address).IsLeftOf((AHAddress) key_address)) {
var con = structs.GetRightNeighborOf(_node.Address);
s = con.Edge;
}
else {
var con = structs.GetLeftNeighborOf(_node.Address);
s = con.Edge;
}
_rpc.Invoke(s, remote_put, "dht.PutHandler", key, value, ttl, unique);
}
catch (Exception) {
lock(_sync) {
_data.RemoveEntry(key, value);
}
throw;
}
return true;
}