total5 0.0.1-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/503.html +65 -0
  2. package/CONTRIBUTING.md +55 -0
  3. package/LICENSE +211 -0
  4. package/README.md +32 -0
  5. package/api.js +289 -0
  6. package/bin/total5 +984 -0
  7. package/builders.js +1435 -0
  8. package/bundles.js +457 -0
  9. package/cache.js +58 -0
  10. package/changelog.txt +3 -0
  11. package/cluster.js +320 -0
  12. package/cms.js +625 -0
  13. package/controller.js +1419 -0
  14. package/cron.js +99 -0
  15. package/debug.js +539 -0
  16. package/edit.js +469 -0
  17. package/error.html +49 -0
  18. package/filestorage.js +1088 -0
  19. package/flow-flowstream.js +3152 -0
  20. package/flow.js +209 -0
  21. package/flowstream.js +1991 -0
  22. package/global.js +125 -0
  23. package/helpers/index.js +32 -0
  24. package/htmlparser.js +650 -0
  25. package/http.js +81 -0
  26. package/image.js +773 -0
  27. package/images.js +747 -0
  28. package/index.js +2658 -0
  29. package/jsonschema.js +691 -0
  30. package/ldap.js +792 -0
  31. package/mail.js +936 -0
  32. package/minificators.js +858 -0
  33. package/nosql-builder.js +440 -0
  34. package/nosql-querybuilder.js +316 -0
  35. package/nosql-reader.js +353 -0
  36. package/nosql-stream.js +617 -0
  37. package/nosql.js +763 -0
  38. package/openclient.js +219 -0
  39. package/package.json +32 -0
  40. package/pause.html +67 -0
  41. package/querybuilder.js +1361 -0
  42. package/release.js +167 -0
  43. package/routing.js +905 -0
  44. package/sourcemap.js +160 -0
  45. package/tangular.js +409 -0
  46. package/templates.js +145 -0
  47. package/templates.json +74 -0
  48. package/tms.js +384 -0
  49. package/tmsclient.js +125 -0
  50. package/todo.txt +7 -0
  51. package/tools/beta.sh +6 -0
  52. package/tools/release.sh +6 -0
  53. package/uibuilder.js +206 -0
  54. package/utils.js +6374 -0
  55. package/viewengine.js +880 -0
  56. package/websocket.js +1939 -0
  57. package/workers.js +129 -0
package/cluster.js ADDED
@@ -0,0 +1,320 @@
1
+ // Total.js Cluster
2
+ // The MIT License
3
+ // Copyright 2018-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ 'use strict';
6
+
7
+ const MAXTHREADLATENCY = 70;
8
+ const FORKS = [];
9
+
10
+ var OPTIONS = {};
11
+ var THREADS = 0;
12
+ var MASTER = null;
13
+ var CONTINUE = false;
14
+ var STATS = [];
15
+ var TIMEOUTS = {};
16
+
17
+ exports.http = function(opt) {
18
+
19
+ process.env.TZ = (opt ? opt.tz : '') || 'utc';
20
+
21
+ // Fork will obtain options automatically via event
22
+ if (F.Cluster.isPrimary) {
23
+ master(opt);
24
+ } else
25
+ fork();
26
+ };
27
+
28
+ exports.restart = function(index) {
29
+ if (index == null) {
30
+ for (var i = 0; i < THREADS; i++)
31
+ setTimeout(index => exports.restart(index), i * 2000, i);
32
+ } else {
33
+ var fork = FORKS[index];
34
+ if (fork) {
35
+ fork.$ready = false;
36
+ fork.removeAllListeners();
37
+ fork.kill(0);
38
+ setTimeout(index => exec(index), 500, index);
39
+ } else
40
+ exec(index);
41
+
42
+ if (!DEBUG)
43
+ console.log('======= ' + (new Date().format('yyyy-MM-dd HH:mm:ss')) + ': restarted thread with index "{0}"'.format(index));
44
+ }
45
+ };
46
+
47
+ function master(opt) {
48
+
49
+ if (!opt.count)
50
+ opt.count = F.Os.cpus().length;
51
+
52
+ opt.auto = opt.count === 'auto';
53
+
54
+ if (opt.auto)
55
+ opt.count = 1;
56
+
57
+ OPTIONS = opt;
58
+
59
+ var memory = process.memoryUsage();
60
+
61
+ if (!process.connected || opt.logs === 'isolated') {
62
+ console.log('==================== CLUSTER =======================');
63
+ console.log('PID : ' + process.pid);
64
+ console.log('Node.js : ' + process.version);
65
+ console.log('Total.js : v' + F.version_header);
66
+ console.log('OS : ' + F.Os.platform() + ' ' + F.Os.release());
67
+ console.log('Memory : ' + memory.heapUsed.filesize(2) + ' / ' + memory.heapTotal.filesize(2));
68
+ console.log('User : ' + F.Os.userInfo().username);
69
+ console.log('OS : ' + F.Os.platform() + ' ' + F.Os.release());
70
+ console.log('====================================================');
71
+ console.log('Thread count : {0}'.format(opt.auto ? 'auto' : opt.count));
72
+ console.log('Date : ' + new Date().format('yyyy-MM-dd HH:mm:ss'));
73
+ console.log('Mode : ' + (opt.release ? 'release' : 'debug'));
74
+ console.log('====================================================\n');
75
+ }
76
+
77
+ if (!opt.release)
78
+ require('./debug').watcher(() => exports.restart());
79
+
80
+ THREADS = opt.count;
81
+
82
+ var check = function(callback) {
83
+ if (CONTINUE)
84
+ callback();
85
+ else
86
+ setTimeout(check, 500, callback);
87
+ };
88
+
89
+ var arr = [];
90
+
91
+ for (let i = 0; i < opt.count; i++)
92
+ arr.push(i);
93
+
94
+ arr.wait(function(index, next) {
95
+ exec(Math.abs(index - THREADS));
96
+ check(next);
97
+ }, function() {
98
+ opt.callback && opt.callback(FORKS);
99
+ });
100
+
101
+ process.title = 'total: cluster';
102
+
103
+ var filename = F.path.join(process.cwd(), 'restart');
104
+ var restart = function(err) {
105
+ if (!err) {
106
+ F.Fs.unlink(filename, NOOP);
107
+ if (!F.restarting) {
108
+ exports.restart();
109
+ F.restarting = true;
110
+ setTimeout(() => F.restarting = false, 30000);
111
+ }
112
+ }
113
+ };
114
+
115
+ var killme = fork => fork.kill();
116
+
117
+ var counter = 0;
118
+ var main = {};
119
+ main.pid = process.pid;
120
+ main.version = {};
121
+ main.version.node = process.version;
122
+ main.version.total = F.version_header;
123
+ main.version.app = CONF.version;
124
+
125
+ setInterval(function() {
126
+
127
+ counter++;
128
+
129
+ if (counter % 10 === 0) {
130
+ main.date = new Date();
131
+ main.threads = THREADS;
132
+ var memory = process.memoryUsage();
133
+ main.memory = (memory.heapUsed / 1024 / 1024).floor(2);
134
+ main.stats = STATS;
135
+ F.Fs.writeFile(process.mainModule.filename + '.json', JSON.stringify(main, null, ' '), NOOP);
136
+ }
137
+
138
+ F.Fs.stat(filename, restart);
139
+
140
+ // Ping
141
+ if (!opt.auto)
142
+ return;
143
+
144
+ var isfree = false;
145
+ var isempty = false;
146
+ var sum = 0;
147
+
148
+ // Auto-ping
149
+ for (var i = 0; i < FORKS.length; i++) {
150
+ var fork = FORKS[i];
151
+ if (fork) {
152
+
153
+ if (fork.$pingoverload)
154
+ fork.$pingoverload--;
155
+
156
+ if (fork.$ping) {
157
+ sum += fork.$ping;
158
+ if (fork.$ping < MAXTHREADLATENCY)
159
+ isfree = true;
160
+ } else
161
+ isempty = true;
162
+
163
+ fork.$pingts = Date.now();
164
+ fork.send('total:ping');
165
+ }
166
+ }
167
+
168
+ if (isfree || isempty) {
169
+
170
+ if (counter % 5 === 0 && !isempty && THREADS > 1) {
171
+
172
+ // try to remove last
173
+ var lastindex = FORKS.length - 1;
174
+ var last = FORKS[lastindex];
175
+ if (last == null) {
176
+ TIMEOUTS[lastindex] && clearTimeout(TIMEOUTS[lastindex]);
177
+ FORKS.splice(lastindex, 1);
178
+ STATS.splice(lastindex, 1);
179
+ THREADS = FORKS.length;
180
+ return;
181
+ }
182
+
183
+ for (var i = 0; i < STATS.length; i++) {
184
+ if (STATS[i].id === last.$id) {
185
+ if (STATS[i].pending < 2) {
186
+ // nothing pending
187
+ fork.$ready = false;
188
+ fork.removeAllListeners();
189
+ fork.kill(0);
190
+ setTimeout(killme, 1000, fork);
191
+ FORKS.splice(lastindex, 1);
192
+ STATS.splice(lastindex, 1);
193
+ }
194
+ break;
195
+ }
196
+ }
197
+ THREADS = FORKS.length;
198
+ }
199
+
200
+ } else if (!opt.limit || THREADS < opt.limit) {
201
+ var avg = (sum / FORKS.length).floor(3);
202
+ if (avg > MAXTHREADLATENCY)
203
+ exec(THREADS++);
204
+ }
205
+
206
+ }, 5000);
207
+ }
208
+
209
+ function message(m) {
210
+
211
+ if (m === 'total:init') {
212
+ OPTIONS.id = this.$id;
213
+ this.send({ TYPE: 'init', bundling: !CONTINUE, id: this.$id, release: !!OPTIONS.release, options: OPTIONS, index: this.$index });
214
+ return;
215
+ }
216
+
217
+ if (m === 'total:ready') {
218
+ CONTINUE = true;
219
+ this.$ready = true;
220
+ return;
221
+ }
222
+
223
+ if (m === 'total:ping') {
224
+ this.$ping = Date.now() - this.$pingts;
225
+ return;
226
+ }
227
+
228
+ if (m === 'total:update') {
229
+ for (let i = 1; i < FORKS.length; i++)
230
+ FORKS[i] && FORKS[i].$ready && FORKS[i].send(m);
231
+ return;
232
+ }
233
+
234
+ if (m === 'total:overload') {
235
+ if (this.$pingoverload) {
236
+ this.$ping = MAXTHREADLATENCY + 1;
237
+ this.$pingoverload = 3; // waits 15 seconds
238
+ }
239
+ return;
240
+ }
241
+
242
+ if (m.TYPE === 'master') {
243
+ if (MASTER && MASTER[m.name]) {
244
+ for (let i = 0, length = MASTER[m.name].length; i < length; i++)
245
+ MASTER[m.name][i](m.a, m.b, m.c, m.d, m.e);
246
+ }
247
+ } else if (m.TYPE === 'stats') {
248
+ let is = false;
249
+ for (let i = 0; i < STATS.length; i++) {
250
+ if (STATS[i].id === m.data.id) {
251
+ m.data.ping = this.$ping;
252
+ STATS[i] = m.data;
253
+ is = true;
254
+ break;
255
+ }
256
+ }
257
+ !is && STATS.push(m.data);
258
+ } else {
259
+
260
+ if (m.TYPE === 'total:emit') {
261
+ if (process.send)
262
+ process.send(m);
263
+ else {
264
+ m.TYPE = 'emit';
265
+ for (let i = 0; i < FORKS.length; i++)
266
+ FORKS[i] && FORKS[i].$ready && FORKS[i].send(m);
267
+ }
268
+ return;
269
+ }
270
+
271
+ if (m.target === 'master') {
272
+ exports.res(m);
273
+ } else {
274
+ for (let i = 0; i < FORKS.length; i++)
275
+ FORKS[i] && FORKS[i].$ready && FORKS[i].send(m);
276
+ }
277
+ }
278
+ }
279
+
280
+ function exec(index) {
281
+
282
+ if (TIMEOUTS[index]) {
283
+ clearTimeout(TIMEOUTS[index]);
284
+ delete TIMEOUTS[index];
285
+ }
286
+
287
+ let fork = F.Cluster.fork();
288
+ fork.$id = index.toString();
289
+ fork.$index = index;
290
+ fork.on('message', message);
291
+ fork.on('exit', function() {
292
+ FORKS[index] = null;
293
+ TIMEOUTS[index] = setTimeout(exports.restart, 1000, index);
294
+ });
295
+
296
+ if (FORKS[index] === undefined)
297
+ FORKS.push(fork);
298
+ else
299
+ FORKS[index] = fork;
300
+
301
+ }
302
+
303
+ function fork() {
304
+ F.on('$message', oninit);
305
+ }
306
+
307
+ function oninit(msg) {
308
+ if (msg.TYPE === 'init') {
309
+ OPTIONS = msg.options;
310
+ THREADS = msg.threads;
311
+ msg.options.bundling = msg.bundling;
312
+ F.isCluster = true;
313
+ F.id = msg.id;
314
+ F.clusterid = msg.id;
315
+ global.DEBUG = msg.release != true;
316
+ OPTIONS.load = '';
317
+ F.http(OPTIONS);
318
+ F.off(msg.TYPE, oninit);
319
+ }
320
+ }