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 @@