webmcp

changeset 480:e09654c4a042

Allow main handlers to use a poll function that indicates when process termination is requested
author jbe
date Tue Jun 06 16:14:33 2017 +0200 (2017-06-06)
parents d3e77b8edb2a
children 416550ff0bb5
files framework/bin/mcp.lua
line diff
     1.1 --- a/framework/bin/mcp.lua	Tue Jun 06 12:08:17 2017 +0200
     1.2 +++ b/framework/bin/mcp.lua	Tue Jun 06 16:14:33 2017 +0200
     1.3 @@ -281,8 +281,12 @@
     1.4    try_exec(WEBMCP_BASE_PATH .. "env/__init.lua")
     1.5  end
     1.6  
     1.7 +-- signal socket (to catch SIGTERM in main handlers)
     1.8 +local sigterm_socket
     1.9 +
    1.10  -- define post-fork initialization function (including loading of "multirand" library)
    1.11  local function postfork_init()
    1.12 +  sigterm_socket = moonbridge_io.signalsocket("TERM")
    1.13    multirand = require "multirand"
    1.14    execute.postfork_initializers()
    1.15  end
    1.16 @@ -336,7 +340,11 @@
    1.17  
    1.18  This function must be called in a configuration file (in the config/ directory) or in pre-fork initializers (in the app/_prefork/ or app/<application name>/_prefork/ directories), unless WebMCP is invoked in interactive mode (in which case any calls of listen{...} are ignored).
    1.19  
    1.20 -This function is a variant of Moonbridge's listen{...} function which has been wrapped for WebMCP. No "prepare", "conenct", or "finish" handler can be set. Instead WebMCP automatically dispatches incoming connections. For interval timers, an interval handler may be specified in each listener.
    1.21 +This function is a variant of Moonbridge's listen{...} function which has been wrapped for WebMCP. No "prepare", "conenct", or "finish" handler can be set. Instead WebMCP automatically dispatches incoming connections. For interval timers and main routines, a handler may be specified in each listener.
    1.22 +
    1.23 +Handlers for main routines (proto = "main") get a poll function passed as first and only parameter. This poll function behaves like moonbridge_io.poll(...) with the exeception that the return value is "terminate", "timeout", or "io" depending whether a termination is requested, a timeout happened, or data is ready for I/O.
    1.24 +
    1.25 +No handler or pre-/postfork initializer should use moonbridge_io.signalsocket(...) directly because this can interfere with signal detection for shutdown.
    1.26  
    1.27  --]]--
    1.28  -- prepare for interactive or listen mode
    1.29 @@ -385,7 +393,20 @@
    1.30      args.connect = function(socket)
    1.31        if socket.main then
    1.32          request.initialize()
    1.33 -        main_handlers[socket.main]()
    1.34 +        local function poll(input_set, output_set, timeout)
    1.35 +          local input_set_copy = table.new(input_set)
    1.36 +          input_set_copy[sigterm_socket] = true
    1.37 +          local timeout = not moonbridge_io.poll(input_set_copy, output_set, timeout)
    1.38 +          local terminate = #(assert(sigterm_socket:read_nb())) > 0
    1.39 +          if terminate then
    1.40 +            return "terminate"
    1.41 +          elseif timeout then
    1.42 +            return "timeout"
    1.43 +          else
    1.44 +            return "io"
    1.45 +          end
    1.46 +        end
    1.47 +        main_handlers[socket.main](poll)
    1.48          io.stderr:write('Main handler "' .. socket.main .. '" terminated. Requesting shutdown.\n')
    1.49          return false
    1.50        elseif socket.interval then

Impressum / About Us