// .split try to call a service // Here, we first check if the requested MDP service is defined or not, // using a MMI lookup to the Majordomo broker. If the service exists, // we send a request and wait for a reply using the conventional MDP // client API. This is not meant to be fast, just very simple: static bool Titanic_ServiceSuccess(Guid uuid, CancellationTokenSource cts) { // Load request message, service will be first frame string fn = TitanicCommon.RequestFilename(uuid); FileStream fs; if (!fn.TryFileOpenRead(out fs)) { // If the client already close request, treat as successful return(true); } fs.Dispose(); ZMessage request = fn.DeserializeFromXml <ZMessage>(); var service = request.Pop(); string servicename = service.ToString(); bool res = false; // Create MDP client session with short timeout using (var client = new MajordomoClient("tcp://127.0.0.1:5555", false)) { client.Set_Timeout(1000); // 1sec client.Set_Retries(1); // only 1 retry // Use MMI protocol to check if service is available ZMessage mmirequest = new ZMessage { service }; bool service_ok; using (var mmireply = client.Send("mmi.service", mmirequest, cts)) service_ok = (mmireply != null && mmireply.First().ToString().Equals("200")); res = false; if (service_ok) { using (ZMessage reply = client.Send(servicename, request, cts)) if (reply != null) { fn = TitanicCommon.ReplyFilename(uuid); reply.SerializeToXml(fn); res = true; } else { request.Dispose(); } } } return(res); }
// .split Titanic close task // The {{titanic.close}} task removes any waiting replies for the request // (specified by UUID). It's idempotent, so it is safe to call more than // once in a row: private static void Titanic_Close(ZContext context, CancellationTokenSource cts, bool verbose) { using (var worker = new MajordomoWorker("tcp://127.0.0.1:5555", "titanic.close", verbose)) { ZMessage reply = null; while (true) { ZMessage request = worker.Recv(reply, cts); if (request == null) { break; } var g = Guid.Parse(request.Pop().ReadString()); var reqfn = TitanicCommon.RequestFilename(g); var repfn = TitanicCommon.ReplyFilename(g); File.Delete(reqfn); File.Delete(repfn); request.Dispose(); reply = new ZMessage(); reply.Add(new ZFrame("200")); } } }
// .split Titanic reply service // The {{titanic.reply}} task checks if there's a reply for the specified // request (by UUID), and returns a 200 (OK), 300 (Pending), or 400 // (Unknown) accordingly: private static void Titanic_Reply(ZContext context, CancellationTokenSource cts, bool verbose) { using (var worker = new MajordomoWorker("tcp://127.0.0.1:5555", "titanic.reply", verbose)) { ZMessage reply = null; while (true) { var request = worker.Recv(reply, cts); if (request == null) { break; // Interrupted, exit } var g = Guid.Parse(request.Pop().ReadString()); var reqfn = TitanicCommon.RequestFilename(g); var repfn = TitanicCommon.ReplyFilename(g); if (File.Exists(repfn)) { reply = repfn.DeserializeFromXml <ZMessage>(); reply.Prepend(new ZFrame("200")); } else { reply = new ZMessage(); if (File.Exists(reqfn)) { reply.Prepend(new ZFrame("300")); //Pending } else { reply.Prepend(new ZFrame("400")); //Unknown } } request.Dispose(); } } }