diff --git a/README.md b/README.md index 6e51b45..ba1ae61 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - +
@@ -17,6 +17,10 @@ Features: - The project only needs to pre-install the Melang interpreter, and no more others need to be installed. +## Web UI Screenshot + + + ## Installation diff --git a/controllers/proc.m b/controllers/proc.m index 84e3721..6ad11c2 100644 --- a/controllers/proc.m +++ b/controllers/proc.m @@ -110,6 +110,10 @@ R['code'] = 400; return J.encode(['code': 400, 'msg': 'Invalid JSON field']); } fi + if (S.int(body['interval']) <= 0) { + R['code'] = 400; + return J.encode(['code': 400, 'msg': "Interval must be a positive integer'"]); + } fi if (S.int(body['replica']) <= 0) { R['code'] = 400; return J.encode(['code': 400, 'msg': "Replica must be a positive integer'"]); diff --git a/coroutines/http.m b/coroutines/http.m index eec00bc..050813a 100644 --- a/coroutines/http.m +++ b/coroutines/http.m @@ -5,10 +5,29 @@ mq = Import('mq'); http = Import('http'); str = Import('str'); +json = Import('json'); while (1) { data = mq.recv('http', 1000); - !sys.is_nil(data) && Tasks[data] && --(Tasks[data]['running']); + if (!sys.is_nil(data)) { + d = json.decode(data); + conf = d['conf']; + name = conf['name']; + if (Tasks[name]['type'] == 'daemon') { + msg = "Daemon Task " + name + " (" + d['alias']; + if (conf['user'] || conf['group']) { + msg += " running as "; + conf['user'] && (msg += conf['user']); + msg += ':'; + conf['group'] && (msg += conf['group']); + } fi + msg += ") start"; + Log('info', msg); + Eval('@/../coroutines/task.m', data, false, d['alias']); + } else { + Tasks[name] && --(Tasks[name]['running']); + } + } fi cron_job_process(); diff --git a/coroutines/task.m b/coroutines/task.m index 9c124ee..4d012bf 100644 --- a/coroutines/task.m +++ b/coroutines/task.m @@ -11,7 +11,9 @@ cmd = conf['cmd']; interval = conf['interval']; -again: +if (type == 'daemon') { + s.msleep(interval); +} fi s.exec(cmd, -1, pid, conf['user'], conf['group'], alias); @@ -25,9 +27,5 @@ msg += ") exit"; Log('info', msg); -if (type == 'daemon') { - s.msleep(interval); - goto again; -} fi -m.send('http', conf['name']); +m.send('http', EVAL_DATA); diff --git a/docs/webui.png b/docs/webui.png new file mode 100644 index 0000000..b35a08d Binary files /dev/null and b/docs/webui.png differ diff --git a/meproc.m b/meproc.m index e3d4406..43f6a1e 100644 --- a/meproc.m +++ b/meproc.m @@ -10,7 +10,7 @@ return; } fi -Log('info', "Meproc v1.0.4. Listen on: " + Conf['ip'] + ':' + Conf['port']); +Log('info', "Meproc v1.0.5. Listen on: " + Conf['ip'] + ':' + Conf['port']); Eval('@/coroutines/http.m'); Eval('@/coroutines/bootstrap.m', nil, false, 'bootstrap'); diff --git a/utils/validator.m b/utils/validator.m index e1d5953..d441cc1 100644 --- a/utils/validator.m +++ b/utils/validator.m @@ -25,7 +25,7 @@ continue; fi } else { - if (!sys.has(data, r['field'])) { + if (!sys.has(data, r['field']) || ((sys.is_str(data[r['field']]) || sys.is_array(data[r['field']])) && !data[r['field']])) { return false; } fi } diff --git a/web/index.html b/web/index.html index b87c652..d72e3aa 100644 --- a/web/index.html +++ b/web/index.html @@ -345,18 +345,18 @@

Start a new task

$('#submitbtn').on('click', function(ev) { ev.preventDefault(); $('#tips').css('display', 'none') - var type = $('#ttype').val() + var type = $('#ttype').val().trim() var data = { - name: $('#tname').val(), - cmd: $('#tcmd').val(), + name: $('#tname').val().trim(), + cmd: $('#tcmd').val().trim(), type: type, - replica: parseInt($('#treplica').val()), + replica: parseInt($('#treplica').val().trim()), } - if ($('#tuser').val()) data.user = $('#tuser').val() - if ($('#tgrp').val()) data.group = $('#tgrp').val() + if ($('#tuser').val()) data.user = $('#tuser').val().trim() + if ($('#tgrp').val()) data.group = $('#tgrp').val().trim() if ($('#tdep').val()) data.deps = $('#tdep').val() - if (type == 'daemon' && $('#tinterval').val()) data.interval = $('#tinterval').val() - if (type == 'cron' && $('#tcron').val()) data.cron = $('#tcron').val() + if (type == 'daemon' && $('#tinterval').val().trim()) data.interval = $('#tinterval').val().trim() + if (type == 'cron' && $('#tcron').val().trim()) data.cron = $('#tcron').val().trim() $.ajax({ url: "http://{{IP}}:{{PORT}}/proc", type: "POST",