diff options
author | Christian Pointner <equinox@spreadspace.org> | 2010-11-14 19:06:41 +0000 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2010-11-14 19:06:41 +0000 |
commit | c3b827d710f62be79837dc581c93db9a2f091d15 (patch) | |
tree | 29f68f4a3f1a6a72ba6a589dfbe505e2c9b5c907 | |
parent | changed module configuration syntax (diff) |
added command queue
git-svn-id: https://svn.spreadspace.org/gcsd/trunk@27 ac14a137-c7f1-4531-abe0-07747231d213
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/command_queue.lua | 77 | ||||
-rw-r--r-- | src/main_loop.lua | 17 | ||||
-rw-r--r-- | src/module_list.lua | 34 | ||||
-rw-r--r-- | src/modules/debug_shell.lua | 7 |
5 files changed, 116 insertions, 20 deletions
diff --git a/src/Makefile b/src/Makefile index abad7a5..91461fd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -53,6 +53,7 @@ C_SRCS := $(C_OBJS:%.o=%.c) LUA_SRCS := client_list.lua \ module_list.lua \ + command_queue.lua \ main_loop.lua LUA_BYTECODE := $(EXECUTABLE).lc diff --git a/src/command_queue.lua b/src/command_queue.lua new file mode 100644 index 0000000..a7ed70b --- /dev/null +++ b/src/command_queue.lua @@ -0,0 +1,77 @@ +-- +-- gcsd +-- +-- gcsd the generic command sequencer daemon can be used to serialize +-- commands sent over various paralell communication channels to a +-- single command output. It can be seen as a multiplexer for any +-- kind of communication between a single resource and various clients +-- which want to submit commands to it or query information from it. +-- gcsd is written in C and Lua. The goal is to provide an easy to +-- understand high level API based on Lua which can be used to +-- implement the business logic of the so formed multiplexer daemon. +-- +-- +-- Copyright (C) 2009-2010 Markus Grueneis <gimpf@spreadspace.org> +-- Christian Pointner <equinox@spreadspace.org> +-- +-- This file is part of gcsd. +-- +-- gcsd is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- any later version. +-- +-- gcsd is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with gcsd. If not, see <http://www.gnu.org/licenses/>. +-- + +local defines = require("defines") + +command_queue = {} + +command_queue.commands = {} +command_queue.current = nil + +function command_queue:enqueue(command, expected_response, timeout) + local new_cmd = {} + new_cmd.command = command + new_cmd.sent = false + new_cmd.expected_response = expected_response + new_cmd.timeout = timeout + + table.insert(self.commands, new_cmd) +end + +function command_queue:command_pending() + return (self.current == nil and #self.commands > 0) +end + +function command_queue:get_current_command() + return self.current +end + +function command_queue:get_next_command() + if(self.current ~= nil) then return nil end + + self.current = self.commands[1] + return self.current.command +end + +function command_queue:command_sent() + if(self.current == nil) then return end + + self.current.sent = true + return self.current.expected_response +end + +function command_queue:command_completed() + if(self.current == nil) then return end + + table.remove(self.commands, 1) + self.current = nil +end diff --git a/src/main_loop.lua b/src/main_loop.lua index 5540dee..ebe42fa 100644 --- a/src/main_loop.lua +++ b/src/main_loop.lua @@ -35,7 +35,7 @@ local defines = require("defines") function get_readables() local readables = {} - for _, module in ipairs(module_list.modules) do + for _, module in ipairs(module_list.inputs) do for _, fd in ipairs(module:get_read_handles()) do table.insert(readables, fd) end @@ -45,13 +45,13 @@ function get_readables() table.insert(readables, fd) end end - + return readables end function get_writeables() local writeables = { } - for _, module in ipairs(module_list.modules) do + for _, module in ipairs(module_list.inputs) do for _, fd in ipairs(module:get_write_handles()) do table.insert(writeables, fd) end @@ -61,11 +61,11 @@ function get_writeables() table.insert(writeables, fd) end end - + return writeables end -function main_loop(opt) +function main_loop(opt) log.printf(log.NOTICE, "main_loop started") local sig = signal.init() @@ -85,7 +85,7 @@ function main_loop(opt) if(return_value == 1) then break end else local ret = reader:read() - if(ret == defines.KILL_DAEMON) then + if(ret == defines.KILL_DAEMON) then return_value = 2 break elseif(ret == defines.KILL_MODULE_CLASS) then @@ -103,6 +103,11 @@ function main_loop(opt) client_list:unregister(writer.client_instance) end end + if(command_queue:command_pending()) then + log.printf(log.DEBUG, "sending pending command: %s", command_queue:get_next_command()) + command_queue:command_sent() + command_queue:command_completed() + end end end diff --git a/src/module_list.lua b/src/module_list.lua index 7c1feae..7683e27 100644 --- a/src/module_list.lua +++ b/src/module_list.lua @@ -32,7 +32,8 @@ module_list = {} -module_list.modules = {} +module_list.inputs = {} +module_list.output = nil function module_list:init(opt) log.printf(log.DEBUG, "gcsd output = %s", opt.cmd_out) @@ -50,19 +51,20 @@ function module_list:init(opt) end package.path = old_path - table.insert(self.modules, dummy:new({})) + self.output = dummy:new({}) + table.insert(self.inputs, dummy:new({})) if(opt.debug) then - table.insert(self.modules, debug_shell:new({["host"]="127.0.0.1", ["port"]="9000"})) - table.insert(self.modules, debug_shell:new({["host"]="127.0.0.1", ["port"]="9001"})) + table.insert(self.inputs, debug_shell:new({["host"]="127.0.0.1", ["port"]="9000"})) + table.insert(self.inputs, debug_shell:new({["host"]="127.0.0.1", ["port"]="9001"})) end end function module_list:unregister(module) - for i, m in ipairs(self.modules) do + for i, m in ipairs(self.inputs) do if(m == module) then - log.printf(log.INFO, "removing module: " .. module.name) + log.printf(log.INFO, "removing input module: " .. module.name) module:cleanup() - table.remove(self.modules, i) + table.remove(self.inputs, i) break end end @@ -71,23 +73,27 @@ end function module_list:unregister_by_class(class) local free_list = {} - for i, m in ipairs(self.modules) do + for i, m in ipairs(self.inputs) do if(m.class == class) then table.insert(free_list, 1, i) end end for _, i in ipairs(free_list) do - log.printf(log.INFO, "removing module: " .. self.modules[i].name) - self.modules[i]:cleanup() - table.remove(self.modules, i) + log.printf(log.INFO, "removing input module: " .. self.inputs[i].name) + self.inputs[i]:cleanup() + table.remove(self.inputs, i) end end function module_list:cleanup() - for _, module in ipairs(self.modules) do - log.printf(log.INFO, "removing module: " .. module.name) + for _, module in ipairs(self.inputs) do + log.printf(log.INFO, "removing input module: " .. module.name) module:cleanup() end - self.modules = {} + if(self.output ~= nil) then + log.printf(log.INFO, "removing output module: " .. self.output.name) + self.output:cleanup() + end + self.inputs = {} end diff --git a/src/modules/debug_shell.lua b/src/modules/debug_shell.lua index 72be4e7..291fc0f 100644 --- a/src/modules/debug_shell.lua +++ b/src/modules/debug_shell.lua @@ -232,6 +232,7 @@ function debug_shell:exec_cmd(socket) elseif(cmd == 'help') then if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end socket.out_buffer = socket.out_buffer .. "!<lua code> execute lua code\n" .. + "cmd <cmd> add the command to the command queue\n" .. "quit quit this debug session\n" .. "ping[ <data>] echo request (response will be 'pong[ <data>]')\n" .. "disable close this debug shell instance and close all connections\n" .. @@ -240,6 +241,12 @@ function debug_shell:exec_cmd(socket) elseif(cmd == 'ping') then if(sep == ' ') then socket.out_buffer = socket.out_buffer .. "pong " .. (param or "") .. "\n" else socket.out_buffer = socket.out_buffer .. "pong\n" end + elseif(cmd == 'cmd') then + if(not param or param == '') then socket.out_buffer = socket.out_buffer .. "Error: please specify a command\n" + else + socket.out_buffer = socket.out_buffer .. "enqueing command: " .. param .. "\n" + command_queue:enqueue(param, nil, nil) + end else socket.out_buffer = socket.out_buffer .. "unknown command\n" end |