@alwaysai/device-agent 1.5.0 → 2.0.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/lib/application-control/config.d.ts.map +1 -1
- package/lib/application-control/config.js +8 -3
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts +1 -5
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +9 -26
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +27 -7
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/index.d.ts +4 -4
- package/lib/application-control/index.d.ts.map +1 -1
- package/lib/application-control/index.js +1 -4
- package/lib/application-control/index.js.map +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +8 -7
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +0 -11
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +5 -54
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/utils.d.ts +0 -4
- package/lib/application-control/utils.d.ts.map +1 -1
- package/lib/application-control/utils.js +1 -24
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/bootstrap-provision.js +3 -2
- package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +10 -15
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +279 -250
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/device-agent.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent.js +11 -9
- package/lib/cloud-connection/device-agent.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +18 -28
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +54 -169
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +71 -165
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +30 -11
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +5 -3
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +59 -27
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +45 -57
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/shadow.d.ts.map +1 -1
- package/lib/cloud-connection/shadow.js +2 -1
- package/lib/cloud-connection/shadow.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +4 -2
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +18 -29
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +3 -3
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +8 -8
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +95 -71
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts.map +1 -1
- package/lib/docker/docker-compose.js +2 -1
- package/lib/docker/docker-compose.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +2 -1
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +7 -7
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -1
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/infrastructure/config-check-utility.d.ts +6 -0
- package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.js +67 -0
- package/lib/infrastructure/config-check-utility.js.map +1 -0
- package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
- package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.test.js +109 -0
- package/lib/infrastructure/config-check-utility.test.js.map +1 -0
- package/lib/infrastructure/device-certificate.d.ts +10 -0
- package/lib/infrastructure/device-certificate.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.js +47 -0
- package/lib/infrastructure/device-certificate.js.map +1 -0
- package/lib/infrastructure/device-certificate.test.d.ts +2 -0
- package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.test.js +24 -0
- package/lib/infrastructure/device-certificate.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.js +44 -0
- package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
- package/lib/infrastructure/required-config-checks.d.ts +2 -0
- package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
- package/lib/infrastructure/required-config-checks.js +30 -0
- package/lib/infrastructure/required-config-checks.js.map +1 -0
- package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
- package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +14 -14
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.js +21 -16
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +1 -2
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts +4 -0
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +52 -6
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/index.d.ts.map +1 -1
- package/lib/subcommands/app/index.js +1 -3
- package/lib/subcommands/app/index.js.map +1 -1
- package/lib/subcommands/app/models.d.ts +0 -11
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +2 -58
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/app/shadow.d.ts.map +1 -1
- package/lib/subcommands/app/shadow.js +6 -5
- package/lib/subcommands/app/shadow.js.map +1 -1
- package/lib/subcommands/app/version.d.ts.map +1 -1
- package/lib/subcommands/app/version.js +2 -4
- package/lib/subcommands/app/version.js.map +1 -1
- package/lib/subcommands/config.d.ts +2 -0
- package/lib/subcommands/config.d.ts.map +1 -0
- package/lib/subcommands/config.js +39 -0
- package/lib/subcommands/config.js.map +1 -0
- package/lib/subcommands/device/clean.d.ts +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +23 -13
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +3 -1
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.js +8 -8
- package/lib/subcommands/device/init.js.map +1 -1
- package/lib/subcommands/device/migrate.d.ts +2 -0
- package/lib/subcommands/device/migrate.d.ts.map +1 -0
- package/lib/subcommands/device/migrate.js +24 -0
- package/lib/subcommands/device/migrate.js.map +1 -0
- package/lib/subcommands/device/refresh.d.ts.map +1 -1
- package/lib/subcommands/device/refresh.js +1 -0
- package/lib/subcommands/device/refresh.js.map +1 -1
- package/lib/subcommands/index.d.ts +1 -1
- package/lib/subcommands/index.d.ts.map +1 -1
- package/lib/subcommands/index.js +3 -1
- package/lib/subcommands/index.js.map +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
- package/lib/util/aai-error.d.ts +12 -0
- package/lib/util/aai-error.d.ts.map +1 -0
- package/lib/util/aai-error.js +11 -0
- package/lib/util/aai-error.js.map +1 -0
- package/lib/util/aws-regions.d.ts +2 -0
- package/lib/util/aws-regions.d.ts.map +1 -0
- package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
- package/lib/util/aws-regions.js.map +1 -0
- package/lib/util/check-for-updates.d.ts.map +1 -1
- package/lib/util/check-for-updates.js +5 -28
- package/lib/util/check-for-updates.js.map +1 -1
- package/lib/util/clean-certs.d.ts.map +1 -1
- package/lib/util/clean-certs.js +5 -4
- package/lib/util/clean-certs.js.map +1 -1
- package/lib/util/directories.d.ts +4 -18
- package/lib/util/directories.d.ts.map +1 -1
- package/lib/util/directories.js +18 -32
- package/lib/util/directories.js.map +1 -1
- package/lib/util/file.d.ts +4 -0
- package/lib/util/file.d.ts.map +1 -1
- package/lib/util/file.js +65 -4
- package/lib/util/file.js.map +1 -1
- package/lib/util/get-device-id.d.ts.map +1 -1
- package/lib/util/get-device-id.js +7 -1
- package/lib/util/get-device-id.js.map +1 -1
- package/lib/util/http-client.js +3 -3
- package/lib/util/http-client.js.map +1 -1
- package/package.json +19 -17
- package/readme.md +12 -32
- package/src/application-control/config.ts +9 -12
- package/src/application-control/environment-variables.test.ts +28 -7
- package/src/application-control/environment-variables.ts +13 -40
- package/src/application-control/index.ts +3 -16
- package/src/application-control/install.ts +15 -10
- package/src/application-control/models.ts +6 -87
- package/src/application-control/utils.ts +0 -28
- package/src/cloud-connection/bootstrap-provision.ts +7 -7
- package/src/cloud-connection/device-agent-cloud-connection.ts +639 -525
- package/src/cloud-connection/device-agent.ts +16 -7
- package/src/cloud-connection/live-updates-handler.test.ts +121 -189
- package/src/cloud-connection/live-updates-handler.ts +99 -234
- package/src/cloud-connection/passthrough-handler.ts +55 -18
- package/src/cloud-connection/shadow-handler.test.ts +45 -57
- package/src/cloud-connection/shadow-handler.ts +103 -57
- package/src/cloud-connection/shadow.ts +4 -1
- package/src/cloud-connection/transaction-manager.test.ts +3 -3
- package/src/cloud-connection/transaction-manager.ts +53 -39
- package/src/device-control/device-control.ts +102 -70
- package/src/docker/docker-compose.ts +3 -2
- package/src/infrastructure/agent-config.test.ts +6 -2
- package/src/infrastructure/agent-config.ts +8 -7
- package/src/infrastructure/config-check-utility.test.ts +154 -0
- package/src/infrastructure/config-check-utility.ts +77 -0
- package/src/infrastructure/device-certificate.test.ts +40 -0
- package/src/infrastructure/device-certificate.ts +58 -0
- package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
- package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
- package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
- package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
- package/src/infrastructure/require-files-present-ready.test.ts +53 -0
- package/src/infrastructure/required-config-checks.ts +33 -0
- package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
- package/src/local-connection/rabbitmq-connection.ts +22 -17
- package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
- package/src/secure-tunneling/secure-tunneling.ts +41 -29
- package/src/subcommands/app/analytics.ts +2 -4
- package/src/subcommands/app/env-vars.ts +72 -9
- package/src/subcommands/app/index.ts +3 -11
- package/src/subcommands/app/models.ts +5 -81
- package/src/subcommands/app/shadow.ts +6 -5
- package/src/subcommands/app/version.ts +3 -4
- package/src/subcommands/config.ts +42 -0
- package/src/subcommands/device/clean.ts +31 -17
- package/src/subcommands/device/index.ts +3 -1
- package/src/subcommands/device/init.ts +11 -11
- package/src/subcommands/device/migrate.ts +20 -0
- package/src/subcommands/device/refresh.ts +1 -0
- package/src/subcommands/index.ts +3 -1
- package/src/util/aai-error.ts +20 -0
- package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
- package/src/util/check-for-updates.ts +14 -30
- package/src/util/clean-certs.ts +8 -4
- package/src/util/directories.ts +23 -67
- package/src/util/file.ts +83 -3
- package/src/util/get-device-id.ts +7 -7
- package/src/util/http-client.ts +2 -2
- package/lib/util/cloud-mode-ready.d.ts +0 -3
- package/lib/util/cloud-mode-ready.d.ts.map +0 -1
- package/lib/util/cloud-mode-ready.js.map +0 -1
- package/lib/util/download-file.d.ts +0 -6
- package/lib/util/download-file.d.ts.map +0 -1
- package/lib/util/download-file.js +0 -25
- package/lib/util/download-file.js.map +0 -1
- package/lib/util/fetch-with-timeout.d.ts +0 -4
- package/lib/util/fetch-with-timeout.d.ts.map +0 -1
- package/lib/util/fetch-with-timeout.js +0 -30
- package/lib/util/fetch-with-timeout.js.map +0 -1
- package/lib/util/parsing.d.ts +0 -2
- package/lib/util/parsing.d.ts.map +0 -1
- package/lib/util/parsing.js +0 -17
- package/lib/util/parsing.js.map +0 -1
- package/src/util/download-file.ts +0 -25
- package/src/util/fetch-with-timeout.ts +0 -35
- package/src/util/parsing.ts +0 -11
|
@@ -1,288 +1,153 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AppLogsPayload,
|
|
3
|
-
keyMirrors,
|
|
4
|
-
LiveStateUpdatesTogglePayload,
|
|
5
|
-
ToClientMessage,
|
|
6
|
-
buildAppLogsMessage,
|
|
7
|
-
buildAppStateMessage,
|
|
8
|
-
buildDeviceStatsMessage,
|
|
9
|
-
StatusResponsePayload,
|
|
10
|
-
buildToClientStatusResponseMessage,
|
|
11
|
-
ToClientMessageTypeValue
|
|
12
|
-
} from '@alwaysai/device-agent-schemas';
|
|
13
|
-
import { getAppLogs } from '../application-control';
|
|
1
|
+
import { ToClientMessageTypeValue } from '@alwaysai/device-agent-schemas';
|
|
14
2
|
import { logger } from '../util/logger';
|
|
15
3
|
import sleep from '../util/sleep';
|
|
16
|
-
import { Publisher } from './publisher';
|
|
17
|
-
import { getAppStatePayload, getDeviceStatsPayload } from './messages';
|
|
18
4
|
import { ALWAYSAI_LIVE_UPDATES_TIMEOUT_MS } from '../environment';
|
|
5
|
+
import { stringifyError } from 'alwaysai/lib/util';
|
|
19
6
|
|
|
20
|
-
const
|
|
7
|
+
const KILL_ALL_TIMEOUT_MS = ALWAYSAI_LIVE_UPDATES_TIMEOUT_MS
|
|
21
8
|
? parseInt(ALWAYSAI_LIVE_UPDATES_TIMEOUT_MS)
|
|
22
9
|
: 80000;
|
|
23
10
|
|
|
11
|
+
export const DEFAULT_INTERVALS_MS = 5000;
|
|
12
|
+
|
|
13
|
+
interface IntervalOptions {
|
|
14
|
+
ms?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
24
17
|
export class LiveUpdatesHandler {
|
|
25
|
-
private
|
|
26
|
-
private
|
|
18
|
+
private killAllTimeout: ReturnType<typeof setTimeout>;
|
|
19
|
+
private livingIntervals: Record<string, ReturnType<typeof setInterval>> = {};
|
|
20
|
+
private livingStreams = new Set<string>();
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
[keyMirrors.toClientMessageType.status_response]: false
|
|
34
|
-
};
|
|
35
|
-
private liveUpdatesSleepIntervals = {
|
|
36
|
-
[keyMirrors.toClientMessageType.device_stats]: 5000,
|
|
37
|
-
[keyMirrors.toClientMessageType.app_state]: 5000,
|
|
38
|
-
[keyMirrors.toClientMessageType.app_logs]: 5000,
|
|
39
|
-
[keyMirrors.toClientMessageType.status_response]: 5000
|
|
40
|
-
};
|
|
22
|
+
constructor() {
|
|
23
|
+
logger.debug(
|
|
24
|
+
`Toggle live updates timeout set to ${KILL_ALL_TIMEOUT_MS} ms`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
|
|
28
|
+
public async enable(
|
|
29
|
+
intervalType: ToClientMessageTypeValue,
|
|
30
|
+
publishingFn: () => Promise<void>,
|
|
31
|
+
transactionId?: string,
|
|
32
|
+
options?: IntervalOptions
|
|
33
|
+
) {
|
|
34
|
+
this.restartKillAllTimeout();
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
36
|
+
const key = this.generateIntervalKey(intervalType, transactionId);
|
|
37
|
+
|
|
38
|
+
clearInterval(this.livingIntervals[key]);
|
|
39
|
+
|
|
40
|
+
// initial publish
|
|
41
|
+
await publishingFn();
|
|
42
|
+
|
|
43
|
+
this.livingIntervals[key] = setInterval(
|
|
44
|
+
async () => {
|
|
45
|
+
try {
|
|
46
|
+
await publishingFn();
|
|
47
|
+
} catch (e) {
|
|
48
|
+
logger.error(
|
|
49
|
+
`Error getting live updates: ${JSON.stringify(
|
|
50
|
+
e
|
|
51
|
+
)}: intervalKey: ${key}. Continuing...`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
options?.ms ? options.ms : DEFAULT_INTERVALS_MS
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public disable(
|
|
60
|
+
intervalType: ToClientMessageTypeValue,
|
|
61
|
+
transactionId?: string
|
|
62
|
+
) {
|
|
63
|
+
const key = this.generateIntervalKey(intervalType, transactionId);
|
|
64
|
+
clearInterval(this.livingIntervals[key]);
|
|
65
|
+
delete this.livingIntervals[key];
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
public async startStream(
|
|
69
|
+
projectId: string,
|
|
70
|
+
streamGetter: () => Promise<NodeJS.ReadableStream | null>,
|
|
71
|
+
publishingFn: (logChunk: string) => void
|
|
72
|
+
) {
|
|
67
73
|
logger.info(`Starting log stream for ${projectId}`);
|
|
68
74
|
|
|
69
|
-
this.
|
|
75
|
+
this.livingStreams.add(projectId);
|
|
70
76
|
|
|
71
|
-
const readable = await this.
|
|
77
|
+
const readable = await this.getStreamWithRetry(projectId, streamGetter);
|
|
72
78
|
|
|
73
79
|
if (readable === null) {
|
|
74
80
|
logger.info(
|
|
75
|
-
`
|
|
81
|
+
`Stream terminated prior to starting. Readable stream is null. ProjectId: ${projectId}`
|
|
76
82
|
);
|
|
77
83
|
return;
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
readable.on('data', async (chunk: Buffer) => {
|
|
81
|
-
if (!this.
|
|
87
|
+
if (!this.livingStreams.has(projectId)) {
|
|
82
88
|
// why doesn't typescript know about this function?
|
|
83
89
|
// @ts-ignore
|
|
84
90
|
readable.destroy();
|
|
85
|
-
logger.info(`
|
|
91
|
+
logger.info(`Stream terminated. ProjectId: ${projectId}`);
|
|
86
92
|
return;
|
|
87
93
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
projectId,
|
|
91
|
-
logChunk: logStr
|
|
92
|
-
};
|
|
93
|
-
const message = buildAppLogsMessage(this.clientId, payload, txId);
|
|
94
|
-
this.publisher.publishToClient(message, logger.silly);
|
|
94
|
+
|
|
95
|
+
publishingFn(chunk.toString());
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
readable.on('error', (error) => {
|
|
98
|
-
logger.error(
|
|
99
|
-
`App log stream terminated for project ${projectId}: ${error}`
|
|
100
|
-
);
|
|
99
|
+
logger.error(`Stream terminated. ProjectId: ${projectId} - ${error}`);
|
|
101
100
|
});
|
|
102
101
|
|
|
103
102
|
readable.on('finished', () => {
|
|
104
|
-
logger.info(`
|
|
103
|
+
logger.info(`Strean complete. ProjectId: ${projectId}`);
|
|
105
104
|
});
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
txId?: string
|
|
111
|
-
): boolean {
|
|
112
|
-
switch (flag) {
|
|
113
|
-
case keyMirrors.toClientMessageType.device_stats:
|
|
114
|
-
case keyMirrors.toClientMessageType.app_state:
|
|
115
|
-
return this.liveUpdatesAlive[flag];
|
|
116
|
-
case keyMirrors.toClientMessageType.status_response: {
|
|
117
|
-
if (!txId) {
|
|
118
|
-
throw new Error(`Transaction ID not provided to continuePublishing!`);
|
|
119
|
-
}
|
|
120
|
-
return this.transactionStatuses.has(txId);
|
|
121
|
-
}
|
|
122
|
-
default:
|
|
123
|
-
logger.error(`Unrecognized publishable flag ${flag}`);
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private getLiveUpdatesInterval(flag: ToClientMessageTypeValue): number {
|
|
129
|
-
const exists = this.liveUpdatesSleepIntervals[flag];
|
|
130
|
-
if (exists) {
|
|
131
|
-
return exists;
|
|
132
|
-
}
|
|
133
|
-
logger.error(`Unrecognized live updates flag ${flag}`);
|
|
134
|
-
return -1;
|
|
107
|
+
public stopStream(streamId: string) {
|
|
108
|
+
this.livingStreams.delete(streamId);
|
|
135
109
|
}
|
|
136
110
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.disableAppStateLiveUpdates();
|
|
141
|
-
this.disableDeviceStatsLiveUpdates();
|
|
142
|
-
this.appLogStreams.clear();
|
|
143
|
-
}, LIVE_UPDATES_TIMEOUT);
|
|
144
|
-
}
|
|
111
|
+
/*=================================================================
|
|
112
|
+
Private interface
|
|
113
|
+
=================================================================*/
|
|
145
114
|
|
|
146
|
-
private async
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
while (this.continuePublishing(messageType, txId)) {
|
|
115
|
+
private async getStreamWithRetry(
|
|
116
|
+
streamId: string,
|
|
117
|
+
streamGetter: () => Promise<NodeJS.ReadableStream | null>
|
|
118
|
+
): Promise<NodeJS.ReadableStream | null> {
|
|
119
|
+
// Retry starting logs until it starts successfully or is terminated
|
|
120
|
+
while (this.livingStreams.has(streamId)) {
|
|
153
121
|
try {
|
|
154
|
-
|
|
155
|
-
this.publisher.publishToClient(message, logger.silly);
|
|
156
|
-
|
|
157
|
-
await sleep(this.getLiveUpdatesInterval(messageType));
|
|
122
|
+
return await streamGetter();
|
|
158
123
|
} catch (e) {
|
|
159
|
-
logger.
|
|
160
|
-
`
|
|
124
|
+
logger.info(
|
|
125
|
+
`Failed to start app logs, retrying in 1 second.\n${stringifyError(
|
|
126
|
+
e
|
|
127
|
+
)}`
|
|
161
128
|
);
|
|
129
|
+
await sleep(1000);
|
|
162
130
|
}
|
|
163
131
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
/*=================================================================
|
|
168
|
-
Public interface
|
|
169
|
-
=================================================================*/
|
|
170
|
-
|
|
171
|
-
constructor(publisher: Publisher, clientId: string) {
|
|
172
|
-
this.publisher = publisher;
|
|
173
|
-
this.clientId = clientId;
|
|
174
|
-
logger.debug(
|
|
175
|
-
`Toggle live updates timeout set to ${LIVE_UPDATES_TIMEOUT} ms`
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
public getDeviceStatsLiveUpdates(): boolean {
|
|
180
|
-
return this.liveUpdatesAlive.device_stats;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
public disableDeviceStatsLiveUpdates() {
|
|
184
|
-
logger.info('Disabled live updates for device_stats');
|
|
185
|
-
this.liveUpdatesAlive.device_stats = false;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
public getAppStateLiveUpdates(): boolean {
|
|
189
|
-
return this.liveUpdatesAlive.app_state;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
public disableAppStateLiveUpdates() {
|
|
193
|
-
logger.info('Disabled live updates for app_state');
|
|
194
|
-
this.liveUpdatesAlive.app_state = false;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
public getAppLogsLiveUpdates() {
|
|
198
|
-
return this.liveUpdatesAlive.app_logs;
|
|
132
|
+
// Case where logs were disabled prior to connecting
|
|
133
|
+
return null;
|
|
199
134
|
}
|
|
200
135
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
this.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
// Don't wait for this call to finish since it loops until disabled
|
|
207
|
-
void this.startPublishingLiveUpdates(
|
|
208
|
-
keyMirrors.toClientMessageType.status_response,
|
|
209
|
-
async () => {
|
|
210
|
-
const payload: StatusResponsePayload = {
|
|
211
|
-
status: keyMirrors.statusResponse.in_progress
|
|
212
|
-
};
|
|
213
|
-
return buildToClientStatusResponseMessage(
|
|
214
|
-
this.clientId,
|
|
215
|
-
payload,
|
|
216
|
-
txId
|
|
217
|
-
);
|
|
218
|
-
},
|
|
219
|
-
txId
|
|
136
|
+
private restartKillAllTimeout() {
|
|
137
|
+
clearTimeout(this.killAllTimeout);
|
|
138
|
+
this.killAllTimeout = setTimeout(() => {
|
|
139
|
+
Object.values(this.livingIntervals).forEach((interval) =>
|
|
140
|
+
clearInterval(interval)
|
|
220
141
|
);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
public async disableTransactionStatus(props: { txId: string }) {
|
|
225
|
-
const { txId } = props;
|
|
226
|
-
this.transactionStatuses.delete(txId);
|
|
227
|
-
|
|
228
|
-
if (this.transactionStatuses.size === 0) {
|
|
229
|
-
this.liveUpdatesAlive.status_response = false;
|
|
230
|
-
}
|
|
142
|
+
this.livingIntervals = {};
|
|
143
|
+
this.livingStreams.clear();
|
|
144
|
+
}, KILL_ALL_TIMEOUT_MS);
|
|
231
145
|
}
|
|
232
146
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
147
|
+
private generateIntervalKey(
|
|
148
|
+
intervalType: ToClientMessageTypeValue,
|
|
149
|
+
transactionId?: string
|
|
236
150
|
) {
|
|
237
|
-
|
|
238
|
-
this.restartLiveUpdatesTimeout();
|
|
239
|
-
|
|
240
|
-
const promises: Promise<void>[] = [];
|
|
241
|
-
|
|
242
|
-
if (deviceStats !== undefined) {
|
|
243
|
-
const currentDeviceStats = this.getDeviceStatsLiveUpdates();
|
|
244
|
-
this.liveUpdatesAlive.device_stats = deviceStats;
|
|
245
|
-
if (deviceStats && currentDeviceStats !== true) {
|
|
246
|
-
// Don't wait for this call to finish since it loops until disabled
|
|
247
|
-
const deviceStatsPromise = this.startPublishingLiveUpdates(
|
|
248
|
-
keyMirrors.toClientMessageType.device_stats,
|
|
249
|
-
async () => {
|
|
250
|
-
const payload = await getDeviceStatsPayload();
|
|
251
|
-
return buildDeviceStatsMessage(this.clientId, payload, txId);
|
|
252
|
-
},
|
|
253
|
-
txId
|
|
254
|
-
);
|
|
255
|
-
promises.push(deviceStatsPromise);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (appState !== undefined) {
|
|
260
|
-
const currentAppState = this.getAppStateLiveUpdates();
|
|
261
|
-
this.liveUpdatesAlive.app_state = appState;
|
|
262
|
-
if (appState && currentAppState !== true) {
|
|
263
|
-
// Don't wait for this call to finish since it loops until disabled
|
|
264
|
-
const appStatePromise = this.startPublishingLiveUpdates(
|
|
265
|
-
keyMirrors.toClientMessageType.app_state,
|
|
266
|
-
async () => {
|
|
267
|
-
const payload = await getAppStatePayload();
|
|
268
|
-
return buildAppStateMessage(this.clientId, payload, txId);
|
|
269
|
-
},
|
|
270
|
-
txId
|
|
271
|
-
);
|
|
272
|
-
promises.push(appStatePromise);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (appLogs !== undefined) {
|
|
277
|
-
const currentAppLogs = this.getAppLogsLiveUpdates();
|
|
278
|
-
if (appLogs.toggle && currentAppLogs !== true) {
|
|
279
|
-
// Don't wait for this call to finish since it loops until disabled
|
|
280
|
-
const appLogPromise = this.startAppLogStream(appLogs.projectId, txId);
|
|
281
|
-
promises.push(appLogPromise);
|
|
282
|
-
} else {
|
|
283
|
-
this.appLogStreams.delete(appLogs.projectId);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return promises;
|
|
151
|
+
return intervalType + `${transactionId ? ':' + transactionId : ''}`;
|
|
287
152
|
}
|
|
288
153
|
}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeviceAgentStatusShadowUpdate,
|
|
3
|
+
PassthroughStatusValue
|
|
4
|
+
} from '@alwaysai/device-agent-schemas/lib/shadow-schema';
|
|
5
|
+
import { stringifyError } from 'alwaysai/lib/util';
|
|
1
6
|
import * as amqp from 'amqplib';
|
|
7
|
+
import { ALWAYSAI_ANALYTICS_PASSTHROUGH } from '../environment';
|
|
2
8
|
import {
|
|
3
9
|
LOCAL_CONNECTION_HOST,
|
|
4
10
|
LOCAL_CONNECTION_PORT,
|
|
5
11
|
LOCAL_CONNECTION_ROUTING_KEY
|
|
6
12
|
} from '../local-connection/constants';
|
|
7
13
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
setupRabbitMQContainer,
|
|
15
|
+
stopRabbitMQContainer
|
|
10
16
|
} from '../local-connection/rabbitmq-connection';
|
|
11
17
|
import { logger } from '../util/logger';
|
|
12
18
|
import sleep from '../util/sleep';
|
|
13
19
|
import { Publisher } from './publisher';
|
|
20
|
+
import { ShadowHandler } from './shadow-handler';
|
|
14
21
|
|
|
15
22
|
const messageQueue: any[] = [];
|
|
16
23
|
const ackQueue: any[] = [];
|
|
@@ -18,12 +25,14 @@ const MAX_LOCAL_CONNECTION_ATTEMPTS = 10;
|
|
|
18
25
|
|
|
19
26
|
export class PassthroughHandler {
|
|
20
27
|
public publisher: Publisher;
|
|
28
|
+
public shadowHandler: ShadowHandler;
|
|
21
29
|
public connection: amqp.Connection | undefined;
|
|
22
30
|
public channel: amqp.Channel;
|
|
23
31
|
public packetQueue;
|
|
24
32
|
|
|
25
|
-
constructor(publisher: Publisher) {
|
|
33
|
+
constructor(publisher: Publisher, shadowHandler: ShadowHandler) {
|
|
26
34
|
this.publisher = publisher;
|
|
35
|
+
this.shadowHandler = shadowHandler;
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
runChannel = async () => {
|
|
@@ -79,9 +88,13 @@ export class PassthroughHandler {
|
|
|
79
88
|
);
|
|
80
89
|
}
|
|
81
90
|
} catch (e) {
|
|
82
|
-
logger.error(
|
|
91
|
+
logger.error(
|
|
92
|
+
`There was a problem parsing RabbitMQ packet!\n${stringifyError(
|
|
93
|
+
e
|
|
94
|
+
)}`
|
|
95
|
+
);
|
|
83
96
|
this.channel.ack(msg);
|
|
84
|
-
logger.debug(
|
|
97
|
+
logger.debug('Problematic packet was acknowledged');
|
|
85
98
|
}
|
|
86
99
|
}
|
|
87
100
|
}
|
|
@@ -138,21 +151,45 @@ export class PassthroughHandler {
|
|
|
138
151
|
}
|
|
139
152
|
}
|
|
140
153
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
private async publishPassthroughStatusUpdate(
|
|
155
|
+
status: PassthroughStatusValue,
|
|
156
|
+
message?: string
|
|
157
|
+
) {
|
|
158
|
+
const deviceAgentPassthroughStatus: DeviceAgentStatusShadowUpdate = {
|
|
159
|
+
passthrough: {
|
|
160
|
+
status: status,
|
|
161
|
+
message: message ?? ''
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
await this.shadowHandler.updateDeviceAgentStatusShadow(
|
|
165
|
+
deviceAgentPassthroughStatus
|
|
144
166
|
);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
`There was a problem maintaining RabbitMQ connection: ${error}`
|
|
152
|
-
);
|
|
153
|
-
throw new Error(
|
|
154
|
-
`There was a problem maintaining RabbitMQ connection: ${error}`
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async setup() {
|
|
170
|
+
if (ALWAYSAI_ANALYTICS_PASSTHROUGH === true) {
|
|
171
|
+
logger.debug(
|
|
172
|
+
`Setting up alwaysAI Local Connection on host: ${LOCAL_CONNECTION_HOST} and channel key: ${LOCAL_CONNECTION_ROUTING_KEY}`
|
|
155
173
|
);
|
|
174
|
+
await this.publishPassthroughStatusUpdate('starting');
|
|
175
|
+
await setupRabbitMQContainer();
|
|
176
|
+
try {
|
|
177
|
+
await this.establishLocalConnection();
|
|
178
|
+
await this.runChannel();
|
|
179
|
+
await this.publishPassthroughStatusUpdate(
|
|
180
|
+
'running',
|
|
181
|
+
`Passthrough running on host: ${LOCAL_CONNECTION_HOST} and channel key: ${LOCAL_CONNECTION_ROUTING_KEY}`
|
|
182
|
+
);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
logger.error(
|
|
185
|
+
`There was a problem maintaining RabbitMQ connection!\n${stringifyError(
|
|
186
|
+
e
|
|
187
|
+
)}`
|
|
188
|
+
);
|
|
189
|
+
await this.publishPassthroughStatusUpdate('error', stringifyError(e));
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
await this.publishPassthroughStatusUpdate('disabled');
|
|
156
193
|
}
|
|
157
194
|
}
|
|
158
195
|
}
|