/// <summary> /// TaskContinuationSources are kept in Broker. This function is called by DipatchMessage() to eventually finalize RPC request. /// <para>All rpc continuations are directed to processes/queues.</para> /// </summary> /// <param name="op"></param> /// <param name="correlationID"></param> /// <param name="result"></param> /// <returns></returns> public static bool TryHandleAsRPCResponse( ServiceBusClient process, RequestData request ) { if (request.Op == "rpc_response" || request.Op == "offer_accepted" || request.Op == "transfer_ack") { if (request.CorrelationId == null) { //error request.Ack(true, false); Tracer.TraceEvent(TraceEventType.Error, 0, "[{0}] missing rpc task continuation cid, message dropped {1}", process, request.ToString()); return true; } TaskCompletionSource<object> tcs; //tracer... if (RPCTaskCompletions.TryRemove(request.CorrelationId, out tcs)) { try { tcs.TrySetResult(request.Response); Tracer.TraceEvent(TraceEventType.Verbose, 0, "[{0}] rpc response op {1} cid {2} response {3}", process, request.Op, request.CorrelationId, request.Response); } catch (Exception ex) { Tracer.TraceEvent(TraceEventType.Error, 0, "[{0}] rpc response op {1} cid {2} response {3} failed dute to {4}", process, request.Op, request.CorrelationId, request.Response, ex.Message); } request.Ack(true, false); return true; } else { //probably result was already set, how did it happen that there are two responses to one request? are they different? possibly not but they could come because of network failue //preserving at-least-once semantics; we ack and drop, making use of indemptodency request.Ack(true, false); Tracer.TraceEvent(TraceEventType.Error, 0, "[{0}] missing rpc task continuation for rpc response {1}, message dropped ", process, request.ToString()); return true; } } return false; }