@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.
- package/.smartconfig.json +37 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.losslessorgclient.d.ts +32 -0
- package/dist_ts/classes.losslessorgclient.js +103 -0
- package/dist_ts/core/classes.error.d.ts +16 -0
- package/dist_ts/core/classes.error.js +29 -0
- package/dist_ts/core/classes.operation.d.ts +17 -0
- package/dist_ts/core/classes.operation.js +70 -0
- package/dist_ts/core/interfaces.d.ts +18 -0
- package/dist_ts/core/interfaces.js +2 -0
- package/dist_ts/index.d.ts +4 -0
- package/dist_ts/index.js +3 -0
- package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
- package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
- package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
- package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
- package/dist_ts/nosqldb/classes.cached-document.js +112 -0
- package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
- package/dist_ts/nosqldb/classes.collection.js +1568 -0
- package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
- package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
- package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
- package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
- package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
- package/dist_ts/nosqldb/classes.connection.js +23 -0
- package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
- package/dist_ts/nosqldb/classes.convenience.js +5 -0
- package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
- package/dist_ts/nosqldb/classes.cursor.js +82 -0
- package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
- package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
- package/dist_ts/nosqldb/classes.db.d.ts +98 -0
- package/dist_ts/nosqldb/classes.db.js +434 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
- package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
- package/dist_ts/nosqldb/classes.doc.js +2976 -0
- package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
- package/dist_ts/nosqldb/classes.easystore.js +199 -0
- package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
- package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
- package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
- package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
- package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
- package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
- package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
- package/dist_ts/nosqldb/classes.persistence.js +34 -0
- package/dist_ts/nosqldb/classes.session.d.ts +28 -0
- package/dist_ts/nosqldb/classes.session.js +246 -0
- package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
- package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
- package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
- package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
- package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
- package/dist_ts/nosqldb/classes.watcher.js +98 -0
- package/dist_ts/nosqldb/index.d.ts +27 -0
- package/dist_ts/nosqldb/index.js +18 -0
- package/dist_ts/nosqldb/logging.d.ts +2 -0
- package/dist_ts/nosqldb/logging.js +3 -0
- package/dist_ts/nosqldb/plugins.d.ts +17 -0
- package/dist_ts/nosqldb/plugins.js +20 -0
- package/dist_ts/nosqldb/shim.d.ts +1 -0
- package/dist_ts/nosqldb/shim.js +8 -0
- package/dist_ts/nosqldb/testsupport.d.ts +3 -0
- package/dist_ts/nosqldb/testsupport.js +3 -0
- package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
- package/dist_ts/objectstorage/classes.bucket.js +939 -0
- package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
- package/dist_ts/objectstorage/classes.connection.js +27 -0
- package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
- package/dist_ts/objectstorage/classes.directory.js +335 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
- package/dist_ts/objectstorage/classes.file.d.ts +91 -0
- package/dist_ts/objectstorage/classes.file.js +255 -0
- package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
- package/dist_ts/objectstorage/classes.listcursor.js +67 -0
- package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
- package/dist_ts/objectstorage/classes.metadata.js +113 -0
- package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
- package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
- package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
- package/dist_ts/objectstorage/classes.trash.js +22 -0
- package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
- package/dist_ts/objectstorage/classes.watcher.js +249 -0
- package/dist_ts/objectstorage/helpers.d.ts +25 -0
- package/dist_ts/objectstorage/helpers.js +215 -0
- package/dist_ts/objectstorage/index.d.ts +13 -0
- package/dist_ts/objectstorage/index.js +13 -0
- package/dist_ts/objectstorage/interfaces.d.ts +276 -0
- package/dist_ts/objectstorage/interfaces.js +2 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
- package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
- package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
- package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
- package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
- package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
- package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
- package/dist_ts/objectstorage/plugins.d.ts +17 -0
- package/dist_ts/objectstorage/plugins.js +23 -0
- package/dist_ts/plugins.d.ts +4 -0
- package/dist_ts/plugins.js +5 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
- package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
- package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
- package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
- package/dist_ts/sqldb/classes.sqltable.js +70 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
- package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
- package/dist_ts/sqldb/clickhouse/index.js +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
- package/dist_ts/sqldb/index.d.ts +6 -0
- package/dist_ts/sqldb/index.js +6 -0
- package/dist_ts/sqldb/interfaces.d.ts +53 -0
- package/dist_ts/sqldb/interfaces.js +19 -0
- package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
- package/dist_ts/sqldb/internal.sqlpool.js +214 -0
- package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
- package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
- package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
- package/dist_ts/sqldb/plugins.mariadb.js +5 -0
- package/docs/source/smartbucket/license.md +19 -0
- package/docs/source/smartclickhouse/license.md +19 -0
- package/license.md +21 -0
- package/package.json +101 -0
- package/readme.md +157 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.losslessorgclient.ts +104 -0
- package/ts/core/classes.error.ts +31 -0
- package/ts/core/classes.operation.ts +60 -0
- package/ts/core/interfaces.ts +24 -0
- package/ts/index.ts +4 -0
- package/ts/nosqldb/classes.atomicdelete.ts +81 -0
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
- package/ts/nosqldb/classes.atomicupdate.ts +99 -0
- package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
- package/ts/nosqldb/classes.bsonassertion.ts +25 -0
- package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
- package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
- package/ts/nosqldb/classes.cached-document.ts +67 -0
- package/ts/nosqldb/classes.collection.ts +2399 -0
- package/ts/nosqldb/classes.collectionfactory.ts +87 -0
- package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
- package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
- package/ts/nosqldb/classes.collectiontopology.ts +645 -0
- package/ts/nosqldb/classes.connection.ts +31 -0
- package/ts/nosqldb/classes.convenience.ts +5 -0
- package/ts/nosqldb/classes.cursor.ts +88 -0
- package/ts/nosqldb/classes.cursoroperation.ts +38 -0
- package/ts/nosqldb/classes.db.ts +637 -0
- package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
- package/ts/nosqldb/classes.doc.ts +4928 -0
- package/ts/nosqldb/classes.easystore.ts +154 -0
- package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
- package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
- package/ts/nosqldb/classes.mongoadministration.ts +867 -0
- package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
- package/ts/nosqldb/classes.operationbudget.ts +75 -0
- package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
- package/ts/nosqldb/classes.persistence.ts +62 -0
- package/ts/nosqldb/classes.session.ts +389 -0
- package/ts/nosqldb/classes.storedinspection.ts +151 -0
- package/ts/nosqldb/classes.testdatabase.ts +272 -0
- package/ts/nosqldb/classes.watcher.ts +96 -0
- package/ts/nosqldb/index.ts +51 -0
- package/ts/nosqldb/logging.ts +3 -0
- package/ts/nosqldb/plugins.ts +37 -0
- package/ts/nosqldb/shim.ts +6 -0
- package/ts/nosqldb/testsupport.ts +13 -0
- package/ts/objectstorage/classes.bucket.ts +1114 -0
- package/ts/objectstorage/classes.connection.ts +36 -0
- package/ts/objectstorage/classes.directory.ts +425 -0
- package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
- package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
- package/ts/objectstorage/classes.file.ts +303 -0
- package/ts/objectstorage/classes.listcursor.ts +89 -0
- package/ts/objectstorage/classes.metadata.ts +134 -0
- package/ts/objectstorage/classes.smartbucket.ts +445 -0
- package/ts/objectstorage/classes.trash.ts +30 -0
- package/ts/objectstorage/classes.watcher.ts +289 -0
- package/ts/objectstorage/helpers.ts +254 -0
- package/ts/objectstorage/index.ts +13 -0
- package/ts/objectstorage/interfaces.ts +389 -0
- package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
- package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
- package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
- package/ts/objectstorage/internal.multipart.planner.ts +90 -0
- package/ts/objectstorage/internal.multipart.stream.ts +606 -0
- package/ts/objectstorage/internal.multipart.types.ts +106 -0
- package/ts/objectstorage/plugins.ts +35 -0
- package/ts/plugins.ts +4 -0
- package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
- package/ts/sqldb/classes.sqlconnection.ts +350 -0
- package/ts/sqldb/classes.sqltable.ts +70 -0
- package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
- package/ts/sqldb/clickhouse/index.ts +16 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
- package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
- package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
- package/ts/sqldb/index.ts +6 -0
- package/ts/sqldb/interfaces.ts +61 -0
- package/ts/sqldb/internal.sqlpool.ts +179 -0
- package/ts/sqldb/plugins.clickhouse.ts +4 -0
- 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
|
+
}
|