2
0

main.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import * as readline from "node:readline";
  2. import mongoose from "mongoose";
  3. import ModuleManager from "@/ModuleManager";
  4. import LogBook from "@/LogBook";
  5. import JobQueue from "@/JobQueue";
  6. import JobStatistics from "@/JobStatistics";
  7. import DataModule from "@/modules/DataModule";
  8. import EventsModule from "./modules/EventsModule";
  9. process.removeAllListeners("uncaughtException");
  10. process.on("uncaughtException", err => {
  11. if (err.name === "ECONNREFUSED" || err.name === "UNCERTAIN_STATE") return;
  12. LogBook.log({
  13. message: err.message,
  14. type: "error",
  15. category: "uncaught-exceptions",
  16. data: { error: err }
  17. });
  18. });
  19. ModuleManager.startup().then(async () => {
  20. const Model = await DataModule.getModel("news");
  21. // console.log("Model", Model);
  22. const abcs = await Model.findOne({}).newest();
  23. console.log("Abcs", abcs);
  24. console.log(
  25. "getData",
  26. await Model.getData({
  27. page: 1,
  28. pageSize: 3,
  29. properties: [
  30. "title",
  31. "markdown",
  32. "status",
  33. "showToNewUsers",
  34. "createdBy"
  35. ],
  36. sort: {},
  37. queries: [
  38. {
  39. data: "v7",
  40. filter: { property: "title" },
  41. filterType: "contains"
  42. }
  43. ],
  44. operator: "and"
  45. })
  46. );
  47. // Model.create({
  48. // name: "Test name",
  49. // someNumbers: [1, 2, 3, 4],
  50. // songs: [],
  51. // aNumber: 941
  52. // });
  53. // Events schedule (was notifications)
  54. const now = Date.now();
  55. EventsModule.schedule("test", 30000);
  56. await EventsModule.subscribe("schedule", "test", async () => {
  57. console.log(`SCHEDULED: ${now} :: ${Date.now()}`);
  58. });
  59. // Events (was cache pub/sub)
  60. await EventsModule.subscribe("event", "test", async value => {
  61. console.log(`PUBLISHED: ${value}`);
  62. });
  63. await EventsModule.publish("test", "a value!");
  64. });
  65. // TOOD remove, or put behind debug option
  66. // eslint-disable-next-line
  67. // @ts-ignore
  68. global.ModuleManager = ModuleManager;
  69. // eslint-disable-next-line
  70. // @ts-ignore
  71. global.JobQueue = JobQueue;
  72. // eslint-disable-next-line
  73. // @ts-ignore
  74. global.rs = () => {
  75. process.exit();
  76. };
  77. // setTimeout(async () => {
  78. // const start = Date.now();
  79. // const x = [];
  80. // while (x.length < 1) {
  81. // x.push(JobQueue.runJob("stations", "addC", {}).catch(() => {}));
  82. // }
  83. // const y = await Promise.all(x);
  84. // console.log(y);
  85. // // const a = await JobQueue.runJob("stations", "addC", {}).catch(() => {});
  86. // // console.log(555, a);
  87. // const difference = Date.now() - start;
  88. // console.log({ difference });
  89. // }, 100);
  90. const rl = readline.createInterface({
  91. input: process.stdin,
  92. output: process.stdout,
  93. completer: (command: string) => {
  94. const parts = command.split(" ");
  95. const commands = ["eval "];
  96. if (parts.length === 1) {
  97. const hits = commands.filter(c => c.startsWith(parts[0]));
  98. return [hits.length ? hits : commands, command];
  99. }
  100. return [];
  101. },
  102. removeHistoryDuplicates: true
  103. });
  104. const shutdown = async () => {
  105. if (rl) {
  106. rl.removeAllListeners();
  107. rl.close();
  108. }
  109. await ModuleManager.shutdown().catch(() => process.exit(1));
  110. process.exit(0);
  111. };
  112. process.on("SIGINT", shutdown);
  113. process.on("SIGQUIT", shutdown);
  114. process.on("SIGTERM", shutdown);
  115. const runCommand = (line: string) => {
  116. const [command, ...args] = line.split(" ");
  117. switch (command) {
  118. case "help": {
  119. console.log("Commands:");
  120. console.log("status - Show module manager and job queue status");
  121. console.log("stats - Shows jobs stats");
  122. console.log("queue - Shows a table of all jobs in the queue");
  123. console.log("active - Shows a table of all jobs currently running");
  124. console.log("jobinfo <jobId> - Print all info about a job");
  125. console.log("eval - Run a command");
  126. console.log("debug");
  127. console.log("log - Change LogBook settings");
  128. break;
  129. }
  130. case "status": {
  131. console.log("Module Manager Status:");
  132. console.table(ModuleManager.getStatus());
  133. console.log("Job Queue Status:");
  134. console.table(JobQueue.getStatus());
  135. break;
  136. }
  137. case "stats": {
  138. console.log("Job Queue Stats:");
  139. console.table(JobStatistics.getStats());
  140. break;
  141. }
  142. case "queue": {
  143. const queueStatus = JobQueue.getQueueStatus().queue;
  144. if (queueStatus.length === 0)
  145. console.log("There are no jobs in the queue.");
  146. else
  147. console.log(
  148. `There are ${queueStatus.length} jobs in the queue.`
  149. );
  150. console.table(queueStatus);
  151. break;
  152. }
  153. case "active": {
  154. const activeStatus = JobQueue.getQueueStatus().active;
  155. if (activeStatus.length === 0)
  156. console.log("There are no active jobs.");
  157. else console.log(`There are ${activeStatus.length} active jobs.`);
  158. console.table(activeStatus);
  159. break;
  160. }
  161. case "jobinfo": {
  162. if (args.length === 0) console.log("Please specify a jobId");
  163. else {
  164. const jobId = args[0];
  165. const job = JobQueue.getJob(jobId);
  166. if (!job) console.log(`Job "${jobId}" not found`);
  167. else {
  168. console.table(job.toJSON());
  169. }
  170. }
  171. break;
  172. }
  173. case "eval": {
  174. const evalCommand = args.join(" ");
  175. console.log(`Running eval command: ${evalCommand}`);
  176. // eslint-disable-next-line no-eval
  177. const response = eval(evalCommand);
  178. console.log(`Eval response: `, response);
  179. break;
  180. }
  181. case "debug": {
  182. // eslint-disable-next-line no-debugger
  183. debugger;
  184. break;
  185. }
  186. case "log": {
  187. const [output, key, action, ...values] = args;
  188. if (
  189. output === undefined ||
  190. key === undefined ||
  191. action === undefined
  192. ) {
  193. console.log(
  194. `Missing required parameters (log <output> <key> <action> [values])`
  195. );
  196. break;
  197. }
  198. let value: any[] | undefined;
  199. if (values !== undefined && values.length >= 1) {
  200. value = values.map(_filter => JSON.parse(_filter));
  201. if (value.length === 1) [value] = value;
  202. }
  203. LogBook
  204. // eslint-disable-next-line
  205. // @ts-ignore
  206. .updateOutput(output, key, action, value)
  207. .then(() => console.log("Successfully updated outputs"))
  208. .catch((err: Error) =>
  209. console.log(`Error updating outputs "${err.message}"`)
  210. );
  211. break;
  212. }
  213. case "getjobs": {
  214. console.log(ModuleManager.getJobs());
  215. break;
  216. }
  217. default: {
  218. if (!/^\s*$/.test(command))
  219. console.log(`Command "${command}" not found`);
  220. }
  221. }
  222. };
  223. rl.on("line", runCommand);