@lossless.org/client 0.1.0

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 (255) hide show
  1. package/.smartconfig.json +37 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/classes.losslessorgclient.d.ts +32 -0
  5. package/dist_ts/classes.losslessorgclient.js +103 -0
  6. package/dist_ts/core/classes.error.d.ts +16 -0
  7. package/dist_ts/core/classes.error.js +29 -0
  8. package/dist_ts/core/classes.operation.d.ts +17 -0
  9. package/dist_ts/core/classes.operation.js +70 -0
  10. package/dist_ts/core/interfaces.d.ts +18 -0
  11. package/dist_ts/core/interfaces.js +2 -0
  12. package/dist_ts/index.d.ts +4 -0
  13. package/dist_ts/index.js +3 -0
  14. package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
  15. package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
  16. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
  17. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
  18. package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
  19. package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
  20. package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
  21. package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
  22. package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
  23. package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
  24. package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
  25. package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
  26. package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
  27. package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
  28. package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
  29. package/dist_ts/nosqldb/classes.cached-document.js +112 -0
  30. package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
  31. package/dist_ts/nosqldb/classes.collection.js +1568 -0
  32. package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
  33. package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
  34. package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
  35. package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
  36. package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
  37. package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
  38. package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
  39. package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
  40. package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
  41. package/dist_ts/nosqldb/classes.connection.js +23 -0
  42. package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
  43. package/dist_ts/nosqldb/classes.convenience.js +5 -0
  44. package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
  45. package/dist_ts/nosqldb/classes.cursor.js +82 -0
  46. package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
  47. package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
  48. package/dist_ts/nosqldb/classes.db.d.ts +98 -0
  49. package/dist_ts/nosqldb/classes.db.js +434 -0
  50. package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
  51. package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
  52. package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
  53. package/dist_ts/nosqldb/classes.doc.js +2976 -0
  54. package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
  55. package/dist_ts/nosqldb/classes.easystore.js +199 -0
  56. package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
  57. package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
  58. package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
  59. package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
  60. package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
  61. package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
  62. package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
  63. package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
  64. package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
  65. package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
  66. package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
  67. package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
  68. package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
  69. package/dist_ts/nosqldb/classes.persistence.js +34 -0
  70. package/dist_ts/nosqldb/classes.session.d.ts +28 -0
  71. package/dist_ts/nosqldb/classes.session.js +246 -0
  72. package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
  73. package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
  74. package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
  75. package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
  76. package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
  77. package/dist_ts/nosqldb/classes.watcher.js +98 -0
  78. package/dist_ts/nosqldb/index.d.ts +27 -0
  79. package/dist_ts/nosqldb/index.js +18 -0
  80. package/dist_ts/nosqldb/logging.d.ts +2 -0
  81. package/dist_ts/nosqldb/logging.js +3 -0
  82. package/dist_ts/nosqldb/plugins.d.ts +17 -0
  83. package/dist_ts/nosqldb/plugins.js +20 -0
  84. package/dist_ts/nosqldb/shim.d.ts +1 -0
  85. package/dist_ts/nosqldb/shim.js +8 -0
  86. package/dist_ts/nosqldb/testsupport.d.ts +3 -0
  87. package/dist_ts/nosqldb/testsupport.js +3 -0
  88. package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
  89. package/dist_ts/objectstorage/classes.bucket.js +939 -0
  90. package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
  91. package/dist_ts/objectstorage/classes.connection.js +27 -0
  92. package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
  93. package/dist_ts/objectstorage/classes.directory.js +335 -0
  94. package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
  95. package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
  96. package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
  97. package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
  98. package/dist_ts/objectstorage/classes.file.d.ts +91 -0
  99. package/dist_ts/objectstorage/classes.file.js +255 -0
  100. package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
  101. package/dist_ts/objectstorage/classes.listcursor.js +67 -0
  102. package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
  103. package/dist_ts/objectstorage/classes.metadata.js +113 -0
  104. package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
  105. package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
  106. package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
  107. package/dist_ts/objectstorage/classes.trash.js +22 -0
  108. package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
  109. package/dist_ts/objectstorage/classes.watcher.js +249 -0
  110. package/dist_ts/objectstorage/helpers.d.ts +25 -0
  111. package/dist_ts/objectstorage/helpers.js +215 -0
  112. package/dist_ts/objectstorage/index.d.ts +13 -0
  113. package/dist_ts/objectstorage/index.js +13 -0
  114. package/dist_ts/objectstorage/interfaces.d.ts +276 -0
  115. package/dist_ts/objectstorage/interfaces.js +2 -0
  116. package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
  117. package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
  118. package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
  119. package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
  120. package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
  121. package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
  122. package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
  123. package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
  124. package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
  125. package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
  126. package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
  127. package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
  128. package/dist_ts/objectstorage/plugins.d.ts +17 -0
  129. package/dist_ts/objectstorage/plugins.js +23 -0
  130. package/dist_ts/plugins.d.ts +4 -0
  131. package/dist_ts/plugins.js +5 -0
  132. package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
  133. package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
  134. package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
  135. package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
  136. package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
  137. package/dist_ts/sqldb/classes.sqltable.js +70 -0
  138. package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
  139. package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
  140. package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
  141. package/dist_ts/sqldb/clickhouse/index.js +13 -0
  142. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
  143. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
  144. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
  145. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
  146. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
  147. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
  148. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
  149. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
  150. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
  151. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
  152. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
  153. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
  154. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
  155. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
  156. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
  157. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
  158. package/dist_ts/sqldb/index.d.ts +6 -0
  159. package/dist_ts/sqldb/index.js +6 -0
  160. package/dist_ts/sqldb/interfaces.d.ts +53 -0
  161. package/dist_ts/sqldb/interfaces.js +19 -0
  162. package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
  163. package/dist_ts/sqldb/internal.sqlpool.js +214 -0
  164. package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
  165. package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
  166. package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
  167. package/dist_ts/sqldb/plugins.mariadb.js +5 -0
  168. package/docs/source/smartbucket/license.md +19 -0
  169. package/docs/source/smartclickhouse/license.md +19 -0
  170. package/license.md +21 -0
  171. package/package.json +101 -0
  172. package/readme.md +157 -0
  173. package/ts/00_commitinfo_data.ts +8 -0
  174. package/ts/classes.losslessorgclient.ts +104 -0
  175. package/ts/core/classes.error.ts +31 -0
  176. package/ts/core/classes.operation.ts +60 -0
  177. package/ts/core/interfaces.ts +24 -0
  178. package/ts/index.ts +4 -0
  179. package/ts/nosqldb/classes.atomicdelete.ts +81 -0
  180. package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
  181. package/ts/nosqldb/classes.atomicupdate.ts +99 -0
  182. package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
  183. package/ts/nosqldb/classes.bsonassertion.ts +25 -0
  184. package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
  185. package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
  186. package/ts/nosqldb/classes.cached-document.ts +67 -0
  187. package/ts/nosqldb/classes.collection.ts +2399 -0
  188. package/ts/nosqldb/classes.collectionfactory.ts +87 -0
  189. package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
  190. package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
  191. package/ts/nosqldb/classes.collectiontopology.ts +645 -0
  192. package/ts/nosqldb/classes.connection.ts +31 -0
  193. package/ts/nosqldb/classes.convenience.ts +5 -0
  194. package/ts/nosqldb/classes.cursor.ts +88 -0
  195. package/ts/nosqldb/classes.cursoroperation.ts +38 -0
  196. package/ts/nosqldb/classes.db.ts +637 -0
  197. package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
  198. package/ts/nosqldb/classes.doc.ts +4928 -0
  199. package/ts/nosqldb/classes.easystore.ts +154 -0
  200. package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
  201. package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
  202. package/ts/nosqldb/classes.mongoadministration.ts +867 -0
  203. package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
  204. package/ts/nosqldb/classes.operationbudget.ts +75 -0
  205. package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
  206. package/ts/nosqldb/classes.persistence.ts +62 -0
  207. package/ts/nosqldb/classes.session.ts +389 -0
  208. package/ts/nosqldb/classes.storedinspection.ts +151 -0
  209. package/ts/nosqldb/classes.testdatabase.ts +272 -0
  210. package/ts/nosqldb/classes.watcher.ts +96 -0
  211. package/ts/nosqldb/index.ts +51 -0
  212. package/ts/nosqldb/logging.ts +3 -0
  213. package/ts/nosqldb/plugins.ts +37 -0
  214. package/ts/nosqldb/shim.ts +6 -0
  215. package/ts/nosqldb/testsupport.ts +13 -0
  216. package/ts/objectstorage/classes.bucket.ts +1114 -0
  217. package/ts/objectstorage/classes.connection.ts +36 -0
  218. package/ts/objectstorage/classes.directory.ts +425 -0
  219. package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
  220. package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
  221. package/ts/objectstorage/classes.file.ts +303 -0
  222. package/ts/objectstorage/classes.listcursor.ts +89 -0
  223. package/ts/objectstorage/classes.metadata.ts +134 -0
  224. package/ts/objectstorage/classes.smartbucket.ts +445 -0
  225. package/ts/objectstorage/classes.trash.ts +30 -0
  226. package/ts/objectstorage/classes.watcher.ts +289 -0
  227. package/ts/objectstorage/helpers.ts +254 -0
  228. package/ts/objectstorage/index.ts +13 -0
  229. package/ts/objectstorage/interfaces.ts +389 -0
  230. package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
  231. package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
  232. package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
  233. package/ts/objectstorage/internal.multipart.planner.ts +90 -0
  234. package/ts/objectstorage/internal.multipart.stream.ts +606 -0
  235. package/ts/objectstorage/internal.multipart.types.ts +106 -0
  236. package/ts/objectstorage/plugins.ts +35 -0
  237. package/ts/plugins.ts +4 -0
  238. package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
  239. package/ts/sqldb/classes.sqlconnection.ts +350 -0
  240. package/ts/sqldb/classes.sqltable.ts +70 -0
  241. package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
  242. package/ts/sqldb/clickhouse/index.ts +16 -0
  243. package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
  244. package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
  245. package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
  246. package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
  247. package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
  248. package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
  249. package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
  250. package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
  251. package/ts/sqldb/index.ts +6 -0
  252. package/ts/sqldb/interfaces.ts +61 -0
  253. package/ts/sqldb/internal.sqlpool.ts +179 -0
  254. package/ts/sqldb/plugins.clickhouse.ts +4 -0
  255. package/ts/sqldb/plugins.mariadb.ts +4 -0
@@ -0,0 +1,305 @@
1
+ import * as plugins from './plugins.js';
2
+ import { SmartdataDb } from './classes.db.js';
3
+ import { managed, setDefaultManagerForDoc } from './classes.collection.js';
4
+ import { SmartDataDbDoc, svDb, unI } from './classes.doc.js';
5
+ import { SmartdataDbWatcher } from './classes.watcher.js';
6
+ import { logger } from './logging.js';
7
+
8
+ @managed()
9
+ export class DistributedClass extends SmartDataDbDoc<DistributedClass, DistributedClass> {
10
+ // INSTANCE
11
+ @unI()
12
+ public id!: string;
13
+
14
+ @svDb()
15
+ public data!: {
16
+ status: 'initializing' | 'bidding' | 'settled' | 'stopped';
17
+ biddingShortcode?: string;
18
+ biddingStartTime?: number;
19
+ lastUpdated: number;
20
+ elected: boolean;
21
+ /**
22
+ * used to store request
23
+ */
24
+ taskRequests: plugins.taskbuffer.distributedCoordination.IDistributedTaskRequest[];
25
+
26
+ /**
27
+ * only used by the leader to convey consultation results
28
+ */
29
+ taskRequestResults: plugins.taskbuffer.distributedCoordination.IDistributedTaskRequestResult[];
30
+ };
31
+ }
32
+
33
+ /**
34
+ * This file implements a distributed coordinator according to the @pushrocks/taskbuffer standard.
35
+ * you should not set up this yourself. Instead, there is a factory on the SmartdataDb class
36
+ * that will take care of setting this up.
37
+ */
38
+ export class SmartdataDistributedCoordinator extends plugins.taskbuffer.distributedCoordination
39
+ .AbstractDistributedCoordinator {
40
+ public readyPromise: Promise<any>;
41
+ public db: SmartdataDb;
42
+ private asyncExecutionStack = new plugins.lik.AsyncExecutionStack();
43
+ public ownInstance!: DistributedClass;
44
+ public distributedWatcher!: SmartdataDbWatcher<DistributedClass>;
45
+
46
+ constructor(dbArg: SmartdataDb) {
47
+ super();
48
+ this.db = dbArg;
49
+ setDefaultManagerForDoc(this, DistributedClass);
50
+ this.readyPromise = this.db.statusConnectedDeferred.promise;
51
+ }
52
+
53
+ // smartdata specific stuff
54
+ public async start() {
55
+ await this.init();
56
+ }
57
+
58
+ public async stop() {
59
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
60
+ if (this.distributedWatcher) {
61
+ await this.distributedWatcher.close();
62
+ }
63
+ if (this.ownInstance?.data.elected) {
64
+ this.ownInstance.data.elected = false;
65
+ }
66
+ if (this.ownInstance?.data.status === 'stopped') {
67
+ logger.log('warn', `stopping a distributed instance that has not been started yet.`);
68
+ }
69
+ this.ownInstance.data.status = 'stopped';
70
+ await this.ownInstance.save();
71
+ logger.log('info', `stopped ${this.ownInstance.id}`);
72
+ });
73
+ }
74
+
75
+ public id = plugins.smartunique.uni('distributedInstance');
76
+
77
+ private startHeartbeat = async () => {
78
+ while (this.ownInstance.data.status !== 'stopped') {
79
+ await this.sendHeartbeat();
80
+ await plugins.smartdelay.delayForRandom(5000, 10000);
81
+ }
82
+ };
83
+
84
+ public async sendHeartbeat() {
85
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
86
+ if (this.ownInstance.data.status === 'stopped') {
87
+ logger.log('debug', `aborted sending heartbeat because status is stopped`);
88
+ return;
89
+ }
90
+ await this.ownInstance.updateFromDb();
91
+ this.ownInstance.data.lastUpdated = Date.now();
92
+ await this.ownInstance.save();
93
+ logger.log('debug', `sent heartbeat for ${this.ownInstance.id}`);
94
+ const allInstances = DistributedClass.getInstances({});
95
+ });
96
+ if (this.ownInstance.data.status === 'stopped') {
97
+ logger.log('info', `aborted sending heartbeat because status is stopped`);
98
+ return;
99
+ }
100
+ const eligibleLeader = await this.getEligibleLeader();
101
+ // not awaiting here because we don't want to block the heartbeat
102
+ this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
103
+ if (!eligibleLeader && this.ownInstance.data.status === 'settled') {
104
+ this.checkAndMaybeLead();
105
+ }
106
+ });
107
+ }
108
+ private async init() {
109
+ await this.readyPromise;
110
+ if (!this.ownInstance) {
111
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
112
+ this.ownInstance = new DistributedClass();
113
+ this.ownInstance.id = this.id;
114
+ this.ownInstance.data = {
115
+ elected: false,
116
+ lastUpdated: Date.now(),
117
+ status: 'initializing',
118
+ taskRequests: [],
119
+ taskRequestResults: [],
120
+ };
121
+ await this.ownInstance.save();
122
+ });
123
+ } else {
124
+ logger.log('warn', `distributed instance already initialized`);
125
+ }
126
+
127
+ // lets enable the heartbeat
128
+ this.startHeartbeat();
129
+
130
+ // lets do a leader check
131
+ await this.checkAndMaybeLead();
132
+
133
+ return this.ownInstance;
134
+ }
135
+
136
+ public async getEligibleLeader() {
137
+ return this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
138
+ const allInstances = await DistributedClass.getInstances({});
139
+ let leaders = allInstances.filter((instanceArg) => instanceArg.data.elected === true);
140
+ const eligibleLeader = leaders.find(
141
+ (leader) =>
142
+ leader.data.lastUpdated >=
143
+ Date.now() - plugins.smarttime.getMilliSecondsFromUnits({ seconds: 20 }),
144
+ );
145
+ return eligibleLeader;
146
+ });
147
+ }
148
+
149
+ // --> leader election
150
+ public async checkAndMaybeLead() {
151
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
152
+ this.ownInstance.data.status = 'initializing';
153
+ await this.ownInstance.save();
154
+ });
155
+ if (await this.getEligibleLeader()) {
156
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
157
+ await this.ownInstance.updateFromDb();
158
+ this.ownInstance.data.status = 'settled';
159
+ await this.ownInstance.save();
160
+ logger.log('info', `${this.ownInstance.id} settled as follower`);
161
+ });
162
+ return;
163
+ } else if (
164
+ (await DistributedClass.getInstances({})).find((instanceArg) => {
165
+ return instanceArg.data.status === 'bidding' &&
166
+ instanceArg.data.biddingStartTime! <= Date.now() - 4000 &&
167
+ instanceArg.data.biddingStartTime! >= Date.now() - 30000;
168
+ })
169
+ ) {
170
+ logger.log('info', 'too late to the bidding party... waiting for next round.');
171
+ return;
172
+ } else {
173
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
174
+ await this.ownInstance.updateFromDb();
175
+ this.ownInstance.data.status = 'bidding';
176
+ this.ownInstance.data.biddingStartTime = Date.now();
177
+ this.ownInstance.data.biddingShortcode = plugins.smartunique.shortId();
178
+ await this.ownInstance.save();
179
+ logger.log('info', 'bidding code stored.');
180
+ });
181
+ logger.log('info', `bidding for leadership...`);
182
+ await plugins.smartdelay.delayFor(plugins.smarttime.getMilliSecondsFromUnits({ seconds: 5 }));
183
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
184
+ let biddingInstances = await DistributedClass.getInstances({});
185
+ biddingInstances = biddingInstances.filter(
186
+ (instanceArg) =>
187
+ instanceArg.data.status === 'bidding' &&
188
+ instanceArg.data.lastUpdated >=
189
+ Date.now() - plugins.smarttime.getMilliSecondsFromUnits({ seconds: 10 }),
190
+ );
191
+ logger.log('info', `found ${biddingInstances.length} bidding instances...`);
192
+ this.ownInstance.data.elected = true;
193
+ for (const biddingInstance of biddingInstances) {
194
+ if (biddingInstance.data.biddingShortcode! < this.ownInstance.data.biddingShortcode!) {
195
+ this.ownInstance.data.elected = false;
196
+ }
197
+ }
198
+ await plugins.smartdelay.delayFor(5000);
199
+ logger.log('info', `settling with status elected = ${this.ownInstance.data.elected}`);
200
+ this.ownInstance.data.status = 'settled';
201
+ await this.ownInstance.save();
202
+ });
203
+ if (this.ownInstance.data.elected) {
204
+ this.leadFunction();
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * when it has been determined
211
+ * that this instance is leading
212
+ * the leading is implemented here
213
+ */
214
+ public async leadFunction() {
215
+ this.distributedWatcher = await DistributedClass.watch({});
216
+
217
+ const currentTaskRequests: Array<{
218
+ taskName: string;
219
+ taskExecutionTime: number;
220
+ /**
221
+ * all instances that requested this task
222
+ */
223
+ requestingDistibutedInstanceIds: string[];
224
+ responseTimeout: plugins.smartdelay.Timeout<any>;
225
+ }> = [];
226
+
227
+ this.distributedWatcher.changeSubject.subscribe({
228
+ next: async (distributedDoc) => {
229
+ if (!distributedDoc) {
230
+ logger.log('info', `registered deletion of instance...`);
231
+ return;
232
+ }
233
+ logger.log('info', distributedDoc);
234
+ logger.log('info', `registered change for ${distributedDoc.id}`);
235
+ distributedDoc;
236
+ },
237
+ });
238
+
239
+ while (this.ownInstance.data.status !== 'stopped' && this.ownInstance.data.elected) {
240
+ const allInstances = await DistributedClass.getInstances({});
241
+ for (const instance of allInstances) {
242
+ if (instance.data.status === 'stopped') {
243
+ await instance.delete();
244
+ }
245
+ }
246
+ await plugins.smartdelay.delayFor(10000);
247
+ }
248
+ }
249
+
250
+ // abstract implemented methods
251
+ public async fireDistributedTaskRequest(
252
+ taskRequestArg: plugins.taskbuffer.distributedCoordination.IDistributedTaskRequest,
253
+ ): Promise<plugins.taskbuffer.distributedCoordination.IDistributedTaskRequestResult> {
254
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
255
+ if (!this.ownInstance) {
256
+ logger.log('error', 'instance need to be started first...');
257
+ return;
258
+ }
259
+ await this.ownInstance.updateFromDb();
260
+ this.ownInstance.data.taskRequests.push(taskRequestArg);
261
+ await this.ownInstance.save();
262
+ });
263
+ await plugins.smartdelay.delayFor(10000);
264
+ const result = await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
265
+ await this.ownInstance.updateFromDb();
266
+ const taskRequestResult = this.ownInstance.data.taskRequestResults.find((resultItem) => {
267
+ return resultItem.requestResponseId === taskRequestArg.requestResponseId;
268
+ });
269
+ return taskRequestResult;
270
+ });
271
+ if (!result) {
272
+ logger.log('warn', 'no result found for task request...');
273
+ return null as any;
274
+ }
275
+ return result;
276
+ }
277
+
278
+ public async updateDistributedTaskRequest(
279
+ infoBasisArg: plugins.taskbuffer.distributedCoordination.IDistributedTaskRequest,
280
+ ): Promise<void> {
281
+ await this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
282
+ const existingInfoBasis = this.ownInstance.data.taskRequests.find((infoBasisItem) => {
283
+ return (
284
+ infoBasisItem.taskName === infoBasisArg.taskName &&
285
+ infoBasisItem.taskExecutionTime === infoBasisArg.taskExecutionTime
286
+ );
287
+ });
288
+ if (!existingInfoBasis) {
289
+ logger.log('warn', 'trying to update a non existing task request... aborting!');
290
+ return;
291
+ }
292
+ Object.assign(existingInfoBasis, infoBasisArg);
293
+ await this.ownInstance.save();
294
+ plugins.smartdelay.delayFor(60000).then(() => {
295
+ this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
296
+ const indexToRemove = this.ownInstance.data.taskRequests.indexOf(existingInfoBasis);
297
+ if (indexToRemove >= 0) {
298
+ this.ownInstance.data.taskRequests.splice(indexToRemove, 1);
299
+ await this.ownInstance.save();
300
+ }
301
+ });
302
+ });
303
+ });
304
+ }
305
+ }