/// <summary> /// Handles messages received from the shared memory inbox. /// </summary> /// <param name="raw">The raw message.</param> private void OnReceive(byte[] raw) { ServiceMsg query; ServiceMsg ack = new ServiceMsg("Ack"); try { query = new ServiceMsg(raw); switch (query.Command) { case "GetStatus": ack["Status"] = service.State.ToString(); break; case "Stop": case "Shutdown": // $todo(jeff.lill): // // For now, I'm going to treat Stop() and Shutdown() the // same by forcing the service to stop immediately. // This should never be called for services running in Native mode // since the ServiceControl instance should have used the native // Windows control mechanisms. For Forms and Console modes, we're // going to call the Service's Stop() method and then terminate the // current process. service.Stop(); Helper.Exit(); break; case "Configure": service.Configure(); break; case "HeartBeat": ack["Alive"] = OnHeartBeat() ? "1" : "0"; break; default: Assertion.Fail("Unexpected ServiceMsg command [{0}].", query.Command); break; } ReplyTo(query, ack); } catch (Exception e) { SysLog.LogException(e); } }
/// <summary> /// Handles messages received from the shared memory inbox. /// </summary> /// <param name="raw">The raw message.</param> private void OnReceive(byte[] raw) { using (TimedLock.Lock(this)) { var msg = new ServiceMsg(raw); if (msg.RefID != refID) { return; // Ignore message that aren't part of the transaction } reply = msg; onReply.Set(); // Wake up the query thread } }
/// <summary> /// Sends the query message to the named service instance and waits for /// a reply. /// </summary> /// <param name="serviceName">The service name.</param> /// <param name="query">The query message.</param> /// <returns>The reply message.</returns> /// <remarks> /// Throws a TimeoutException if the service doesn't respond by MaxWaitTime. /// </remarks> private ServiceMsg Query(string serviceName, ServiceMsg query) { using (TimedLock.Lock(this)) { refID = Helper.NewGuid(); query.RefID = refID; } query["Reply-To"] = ControlMemPrefix + id.ToString(); outbox.Send(ServiceMemPrefix + serviceName, query.ToBytes()); if (!onReply.WaitOne(MaxWaitTime, false)) { throw new System.TimeoutException(); } if (reply.Command != "Ack") { throw new InvalidOperationException("Invalid Service response."); } return(reply); }
/// <summary> /// Sends a reply to the query passed. /// </summary> /// <param name="query">The query message received.</param> /// <param name="ack">The reply.</param> private void ReplyTo(ServiceMsg query, ServiceMsg ack) { ack.RefID = query.RefID; outbox.Send(query["Reply-To"], ack.ToBytes()); }