-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstopInstance.ts
125 lines (115 loc) · 3.67 KB
/
stopInstance.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { waitForEventEmitterPowerData } from "../../events/eventEmitter";
import {
InstanceData,
instancesData,
instancesStartingTimeout,
serverData,
} from "../../store";
import { stopSocket } from "../socket/control";
export type StopReport = {
success: boolean;
statusCode: number;
message: string;
instanceId?: string;
instance?: InstanceData;
};
type Config = {
emergency?: boolean;
timeout?: boolean;
};
/**
* Stops a certain instance and updates server-wide data accordingly.
* @param {string} id - identifier for the instance.
* @param {boolean} emergency - whether the stop is an emergency stop.
* @returns {StopReport} An object indicating the operation's report.
*/
export const stopInstance = async (
id: string,
config?: Config,
): Promise<StopReport> => {
let triggerPowerOff = config?.emergency ? true : false;
if (!instancesData[id]) {
return {
success: false,
statusCode: 404,
message: `Instance with ID ${id} does not exist.`,
};
}
if (instancesStartingTimeout[id]) {
clearTimeout(instancesStartingTimeout[id]);
delete instancesStartingTimeout[id];
}
if (instancesData[id].stopTimestamp) {
return {
success: true,
statusCode: 200,
instance: instancesData[id],
message: `Instance with ID ${id} is already stopped.`,
};
}
serverData.instancesStopping.push(id);
instancesData[id].stopTimestamp = new Date();
let report: StopReport = {
statusCode: 200,
success: true,
message: `Instance with ID ${id} stopped successfully.`,
instanceId: id,
};
/**
* If the instance running is the last one, trigger a power off.
*/
if (
serverData.runningInstances.length === 1 &&
serverData.runningInstances[0] === id
) {
const stoppingId = config?.emergency
? "<emergency>"
: config?.timeout
? "<timeout>"
: id;
serverData.powerStatus[serverData.powerStatus.length - 1].powerOff = {
instanceId: stoppingId,
timestamp: new Date(),
};
instancesData[id].powerOffTimestamp = new Date();
instancesData[id].isEmergencyStopped = config?.emergency ? true : false;
triggerPowerOff = true;
}
serverData.runningInstances = serverData.runningInstances.filter(
(instanceId) => instanceId !== id,
);
if (instancesData[id].timeout) {
serverData.runningInstancesWithTimeout =
serverData.runningInstancesWithTimeout.filter(
(instanceId) => instanceId !== id,
);
}
/**
* If the stop is an emergency stop, stop the socket and wait for the power off event.
* If is an emergency stop, we handle it differently and more efficiently
*/
if (!config?.emergency && triggerPowerOff) {
try {
stopSocket();
const powerData = await waitForEventEmitterPowerData();
if (!powerData || powerData === "ON") {
return {
success: false,
statusCode: 500,
message: "An error occurred while stopping the socket",
};
}
} catch (e) {
return {
success: false,
statusCode: 500,
message: "An error occurred while stopping the socket",
};
}
}
serverData.instancesStopping = serverData.instancesStopping.filter(
(instance) => instance !== id,
);
report.instance = instancesData[id];
return report;
};