/**
* This dispatches the particular methods this class provides.
* Currently, the only invokable method is:
* "Start".
*/
public void HandleRpc(ISender caller, string method, IList args, object req_state)
{
int part_idx = method.IndexOf(':');
if (part_idx == -1)
{
if (method == "Start")
{
IDictionary ht = (IDictionary)args[0];
MapReduceArgs mr_args = new MapReduceArgs(ht);
string task_name = mr_args.TaskName;
MapReduceTask task;
if (_name_to_task.TryGetValue(task_name, out task))
{
MapReduceComputation mr = new MapReduceComputation(_node, req_state, task, mr_args);
mr.Start();
}
else
{
throw new AdrException(-32608, "No mapreduce task with name: " + task_name);
}
}
else if (method == "AddHandler")
{
//Make sure this is local:
ISender tmp_call = caller;
bool islocal = tmp_call is Node;
while (!islocal && tmp_call is IWrappingSender)
{
tmp_call = ((IWrappingSender)tmp_call).WrappedSender;
islocal = tmp_call is Node;
}
if (!islocal)
{
throw new AdrException(-32601, "AddHandler only valid for local callers");
}
SubscribeTask(new RpcMapReduceTask(_node, (IDictionary)args[0]));
_rpc.SendResult(req_state, null);
}
else
{
throw new AdrException(-32601, "No Handler for method: " + method);
}
}
else
{
//This is a reference to a specific part of a task:
string part = method.Substring(0, part_idx);
string task_name = method.Substring(part_idx + 1);
MapReduceTask task;
if (false == _name_to_task.TryGetValue(task_name, out task))
{
throw new AdrException(-32608, "No mapreduce task with name: " + task_name);
}
if (part == "tree")
{
var mra = new MapReduceArgs((IDictionary)args[0]);
var tree_res = new Channel(1, req_state);
tree_res.CloseEvent += this.HandleTree;
task.GenerateTree(tree_res, mra);
}
else if (part == "reduce")
{
//Prepare the RpcResult:
var rres_d = (IDictionary)args[2];
ISender send = SenderFactory.CreateInstance(_node, (string)rres_d["sender"]);
var rres = new RpcResult(send, rres_d["result"]);
Channel reduce_res = new Channel(1, req_state);
reduce_res.CloseEvent += this.HandleReduce;
task.Reduce(reduce_res, args[0], args[1], rres);
}
else if (part == "map")
{
Channel map_res = new Channel(1, req_state);
map_res.CloseEvent += this.HandleMap;
task.Map(map_res, args[0]);
}
else
{
throw new AdrException(-32608,
String.Format("No mapreduce task({0}) part with name: {1}", task_name, part));
}
}
}