querysub 0.512.0 → 0.514.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/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
2
2
|
import { qreact } from "../../4-dom/qreact";
|
|
3
|
+
import { t } from "../../2-proxy/schema2";
|
|
4
|
+
import { Querysub } from "../../4-querysub/Querysub";
|
|
3
5
|
import { DEFAULT_OVERLAP_TIME, MachineServiceController, MachineInfo, ServiceConfig } from "../machineSchema";
|
|
4
6
|
import { showFullscreenModal } from "../../5-diagnostics/FullscreenModal";
|
|
5
7
|
import { css } from "../../4-dom/css";
|
|
6
8
|
import { formatTime } from "socket-function/src/formatting/format";
|
|
7
9
|
import { formatDateJSX } from "../../misc/formatJSX";
|
|
8
10
|
import { MachineController } from "../machineController";
|
|
11
|
+
import { deepCloneJSON } from "socket-function/src/misc";
|
|
9
12
|
import { unique } from "../../misc";
|
|
10
13
|
import { CommitModal } from "./CommitModal";
|
|
11
14
|
|
|
@@ -39,6 +42,9 @@ export const buttonStyle = css.pad2(12, 8).button.bord2(0, 0, 20).fontWeight("bo
|
|
|
39
42
|
export class UpdateButtons extends qreact.Component<{
|
|
40
43
|
services: ServiceConfig[];
|
|
41
44
|
}> {
|
|
45
|
+
state = t.state({
|
|
46
|
+
isDeploying: t.type(false),
|
|
47
|
+
});
|
|
42
48
|
render() {
|
|
43
49
|
let controller = MachineServiceController(SocketFunction.browserNodeId());
|
|
44
50
|
const gitInfo = controller.getGitInfo();
|
|
@@ -94,18 +100,31 @@ export class UpdateButtons extends qreact.Component<{
|
|
|
94
100
|
{outdatedServices.length > 0 && gitInfo &&
|
|
95
101
|
<button
|
|
96
102
|
className={buttonStyle.hsl(120, 70, 90)}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
disabled={this.state.isDeploying}
|
|
104
|
+
onClick={() => {
|
|
105
|
+
this.state.isDeploying = true;
|
|
106
|
+
// Props are synchronized state, so everything the async work needs is cloned into plain locals HERE, in the synced part
|
|
107
|
+
let toDeploy = outdatedServices.map(service => {
|
|
108
|
+
let updated = deepCloneJSON(service);
|
|
109
|
+
updated.parameters.gitRef = gitInfo.latestRef;
|
|
100
110
|
// Release with the configured overlap, so the new instances are running before the old ones shut down
|
|
101
|
-
let overlap =
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
111
|
+
let overlap = updated.parameters.overlapTime || DEFAULT_OVERLAP_TIME;
|
|
112
|
+
updated.parameters.releaseTime = Date.now() + overlap;
|
|
113
|
+
return updated;
|
|
114
|
+
});
|
|
115
|
+
Querysub.onCommitFinished(async () => {
|
|
116
|
+
try {
|
|
117
|
+
await controller.setServiceConfigs.promise(toDeploy);
|
|
118
|
+
} finally {
|
|
119
|
+
Querysub.commit(() => {
|
|
120
|
+
this.state.isDeploying = false;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
});
|
|
105
124
|
}}
|
|
106
125
|
>
|
|
107
126
|
<div>
|
|
108
|
-
{bigEmoji("🎯")} <span>Deploy & Restart All ({outdatedServices.length}) Services</span>
|
|
127
|
+
{bigEmoji("🎯")} <span>{this.state.isDeploying && "⏳ Deploying..." || `Deploy & Restart All (${outdatedServices.length}) Services`}</span>
|
|
109
128
|
</div>
|
|
110
129
|
<div className={css.hbox(5)}>
|
|
111
130
|
<b>New</b>
|
|
@@ -124,6 +143,9 @@ export class UpdateButtons extends qreact.Component<{
|
|
|
124
143
|
export class UpdateServiceButtons extends qreact.Component<{
|
|
125
144
|
service: ServiceConfig;
|
|
126
145
|
}> {
|
|
146
|
+
state = t.state({
|
|
147
|
+
isDeploying: t.type(false),
|
|
148
|
+
});
|
|
127
149
|
render() {
|
|
128
150
|
let controller = MachineServiceController(SocketFunction.browserNodeId());
|
|
129
151
|
const gitInfo = controller.getGitInfo();
|
|
@@ -134,16 +156,28 @@ export class UpdateServiceButtons extends qreact.Component<{
|
|
|
134
156
|
return <>
|
|
135
157
|
{gitRef !== gitInfo.latestRef && <button
|
|
136
158
|
className={buttonStyle.hsl(120, 70, 90).alignSelf("stretch")}
|
|
137
|
-
|
|
138
|
-
|
|
159
|
+
disabled={this.state.isDeploying}
|
|
160
|
+
onClick={() => {
|
|
161
|
+
this.state.isDeploying = true;
|
|
162
|
+
// Props are synchronized state, so everything the async work needs is cloned into plain locals HERE, in the synced part
|
|
163
|
+
let service = deepCloneJSON(this.props.service);
|
|
164
|
+
service.parameters.gitRef = gitInfo.latestRef;
|
|
139
165
|
// Release with the configured overlap, so the new instances are running before the old ones shut down
|
|
140
|
-
let overlap =
|
|
141
|
-
|
|
142
|
-
|
|
166
|
+
let overlap = service.parameters.overlapTime || DEFAULT_OVERLAP_TIME;
|
|
167
|
+
service.parameters.releaseTime = Date.now() + overlap;
|
|
168
|
+
Querysub.onCommitFinished(async () => {
|
|
169
|
+
try {
|
|
170
|
+
await controller.setServiceConfigs.promise([service]);
|
|
171
|
+
} finally {
|
|
172
|
+
Querysub.commit(() => {
|
|
173
|
+
this.state.isDeploying = false;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
143
177
|
}}
|
|
144
178
|
>
|
|
145
179
|
<div>
|
|
146
|
-
{bigEmoji("🎯", -4)} <span>Update to New & Restart</span>
|
|
180
|
+
{bigEmoji("🎯", -4)} <span>{this.state.isDeploying && "⏳ Deploying..." || "Update to New & Restart"}</span>
|
|
147
181
|
</div>
|
|
148
182
|
<div className={css.hbox(5)}>
|
|
149
183
|
<b>New</b>
|
|
@@ -161,6 +195,9 @@ export class UpdateServiceButtons extends qreact.Component<{
|
|
|
161
195
|
export class DeployMachineButtons extends qreact.Component<{
|
|
162
196
|
machines: MachineInfo[];
|
|
163
197
|
}> {
|
|
198
|
+
state = t.state({
|
|
199
|
+
isDeploying: t.type(false),
|
|
200
|
+
});
|
|
164
201
|
render() {
|
|
165
202
|
let controller = MachineServiceController(SocketFunction.browserNodeId());
|
|
166
203
|
const gitInfo = controller.getGitInfo();
|
|
@@ -174,25 +211,38 @@ export class DeployMachineButtons extends qreact.Component<{
|
|
|
174
211
|
return <>
|
|
175
212
|
{outdatedMachines.length > 0 && <div
|
|
176
213
|
className={buttonStyle.alignSelf("stretch").hsl(120, 70, 50)}
|
|
177
|
-
onClick={
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
214
|
+
onClick={() => {
|
|
215
|
+
if (this.state.isDeploying) return;
|
|
216
|
+
this.state.isDeploying = true;
|
|
217
|
+
// Props are synchronized state, so everything the async work needs is captured HERE, in the synced part
|
|
218
|
+
let machineNodeIds = outdatedMachines.map(machine => machine.applyNodeId);
|
|
219
|
+
let gitRef = gitInfo.latestRef;
|
|
220
|
+
Querysub.onCommitFinished(async () => {
|
|
221
|
+
try {
|
|
222
|
+
let machineController = MachineController(SocketFunction.browserNodeId());
|
|
223
|
+
try {
|
|
224
|
+
await Promise.allSettled(machineNodeIds.map(machineNodeId => {
|
|
225
|
+
return machineController.deployMachineFromBrowser.promise({
|
|
226
|
+
machineNodeId,
|
|
227
|
+
gitRef,
|
|
228
|
+
});
|
|
229
|
+
}));
|
|
230
|
+
} catch (error) {
|
|
231
|
+
// They should always end with a disconnect (which means the machine updated, so obviously it disconnected from us)
|
|
232
|
+
if (!String(error).includes("disconnected")) {
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} finally {
|
|
237
|
+
Querysub.commit(() => {
|
|
238
|
+
this.state.isDeploying = false;
|
|
184
239
|
});
|
|
185
|
-
}));
|
|
186
|
-
} catch (error) {
|
|
187
|
-
// They should always end with a disconnect (which means the machine updated, so obviously it disconnected from us)
|
|
188
|
-
if (!String(error).includes("disconnected")) {
|
|
189
|
-
throw error;
|
|
190
240
|
}
|
|
191
|
-
}
|
|
241
|
+
});
|
|
192
242
|
}}
|
|
193
243
|
>
|
|
194
244
|
<div>
|
|
195
|
-
{bigEmoji("🎯", -4)} <span>Deploy {outdatedMachines.length} Machines</span>
|
|
245
|
+
{bigEmoji("🎯", -4)} <span>{this.state.isDeploying && "⏳ Deploying..." || `Deploy ${outdatedMachines.length} Machines`}</span>
|
|
196
246
|
</div>
|
|
197
247
|
<div className={css.hbox(5)}>
|
|
198
248
|
<b>New</b>
|