querysub 0.694.0 → 0.696.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,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.694.0",
3
+ "version": "0.696.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -595,19 +595,6 @@ export class ServiceDetailPage extends qreact.Component {
595
595
  Old instances shut down in {formatTime(scheduledDeploy.switchTime + scheduledDeploy.overlapTime - now)} ({formatDateTimeDetailed(scheduledDeploy.switchTime + scheduledDeploy.overlapTime)})
596
596
  </div>
597
597
  <div className={css.hbox(8)}>
598
- <button
599
- className={css.pad2(12, 8).button.bord2(0, 0, 20).hsl(0, 70, 90)}
600
- onClick={() => {
601
- this.runControllerAction(async () => {
602
- let cancelled = await controller.cancelScheduledDeploy.promise(selectedServiceId);
603
- // Keep the cancelled changes in the editor, so they aren't lost (Discard Changes drops them)
604
- Querysub.commit(() => {
605
- this.state.editorState = cancelled;
606
- });
607
- });
608
- }}>
609
- Cancel Scheduled Deploy
610
- </button>
611
598
  <button
612
599
  className={css.pad2(12, 8).button.bord2(45, 80, 35).hsl(45, 85, 82)}
613
600
  disabled={this.state.isDeploying}
@@ -106,22 +106,59 @@ export function confirmNoOverlapDeploy(actionLabel: string, onConfirm: () => voi
106
106
  });
107
107
  }
108
108
 
109
+ const CONFIRM_LIST_MAX_HEIGHT = 220;
110
+
111
+ /** Deploying every outdated service restarts all of them at once, which is most of the cluster — worth naming what is about to restart before it happens. */
112
+ class DeployAllConfirmModal extends qreact.Component<{ titles: string[]; latestRef: string; onConfirm: () => void }> {
113
+ render() {
114
+ let count = this.props.titles.length;
115
+ return <div className={css.vbox(14).maxWidth(560)}>
116
+ <div className={css.fontSize(18).boldStyle}>Deploy {count} service{count === 1 && "" || "s"}?</div>
117
+ <div>
118
+ Each one restarts onto {this.props.latestRef.slice(0, 6)}. The old instances keep running for {formatTime(DEFAULT_OVERLAP_TIME)} before shutting down, so there is somewhere for connections to go while clients move across.
119
+ </div>
120
+ <div className={css.vbox(2).fillWidth.maxHeight(CONFIRM_LIST_MAX_HEIGHT).overflowAuto}>
121
+ {this.props.titles.map(title => <div>{title}</div>)}
122
+ </div>
123
+ <div className={css.hbox(10)}>
124
+ <button
125
+ className={buttonStyle.hsl(120, 70, 90)}
126
+ onClick={() => {
127
+ closeAllModals();
128
+ this.props.onConfirm();
129
+ }}
130
+ >
131
+ Deploy & Restart All ({count})
132
+ </button>
133
+ <button className={buttonStyle.hsl(0, 0, 90)} onClick={() => closeAllModals()}>
134
+ Cancel
135
+ </button>
136
+ </div>
137
+ </div>;
138
+ }
139
+ }
140
+ export function confirmDeployAll(config: { titles: string[]; latestRef: string; onConfirm: () => void }) {
141
+ showFullscreenModal({
142
+ content: <DeployAllConfirmModal titles={config.titles} latestRef={config.latestRef} onConfirm={config.onConfirm} />,
143
+ });
144
+ }
145
+
109
146
  export class UpdateButtons extends qreact.Component<{
110
147
  services: ServiceConfig[];
111
148
  }> {
112
149
  state = t.state({
113
150
  isDeploying: t.type(false),
114
151
  });
115
- // Deploys all outdated services to latestRef, always immediately. The overlap is what keeps the service up - the old instances keep running for it, so connections have somewhere to go while clients move across. noOverlap kills them at once instead.
116
- private deployAll(outdatedServices: ServiceConfig[], latestRef: string, noOverlap: boolean) {
152
+ // Deploys all outdated services to latestRef, always immediately. The overlap is what keeps the service up - the old instances keep running for it, so connections have somewhere to go while clients move across.
153
+ private deployAll(outdatedServices: ServiceConfig[], latestRef: string) {
117
154
  this.state.isDeploying = true;
118
155
  // Props are synchronized state, so everything the async work needs is cloned into plain locals HERE, in the synced part
119
156
  let toDeploy = outdatedServices.map(service => {
120
157
  let updated = deepCloneJSON(service);
121
158
  updated.parameters.gitRef = latestRef;
122
159
  updated.parameters.releaseTime = Date.now();
123
- // Always set, never inherited: the overlap belongs to the deploy being made, and leaving the previous deploy's value in place means one no-overlap deploy silently makes every later deploy a no-overlap one. A ternary, as 0 is the value we actually want here and it is falsy.
124
- updated.parameters.overlapTime = noOverlap ? 0 : DEFAULT_OVERLAP_TIME;
160
+ // Always set, never inherited: the overlap belongs to the deploy being made, and leaving the previous deploy's value in place means one no-overlap deploy silently makes every later deploy a no-overlap one.
161
+ updated.parameters.overlapTime = DEFAULT_OVERLAP_TIME;
125
162
  return updated;
126
163
  });
127
164
  let controller = MachineServiceController(SocketFunction.browserNodeId());
@@ -190,9 +227,13 @@ export class UpdateButtons extends qreact.Component<{
190
227
  <button
191
228
  className={buttonStyle.hsl(120, 70, 90)}
192
229
  disabled={this.state.isDeploying}
193
- title="Deploys now; the old instances keep running for their configured overlap before shutting down"
230
+ title="Asks first, then deploys; the old instances keep running for their configured overlap before shutting down"
194
231
  onClick={() => {
195
- this.deployAll(outdatedServices, gitInfo.latestRef, false);
232
+ confirmDeployAll({
233
+ titles: outdatedServices.map(service => service.info.title),
234
+ latestRef: gitInfo.latestRef,
235
+ onConfirm: () => this.deployAll(outdatedServices, gitInfo.latestRef),
236
+ });
196
237
  }}
197
238
  >
198
239
  <div>
@@ -207,20 +248,6 @@ export class UpdateButtons extends qreact.Component<{
207
248
  <RenderGitRefInfo gitRef={ref} />
208
249
  </div>)}
209
250
  </button>
210
- <button
211
- className={buttonStyle.hsl(0, 85, 70)}
212
- disabled={this.state.isDeploying}
213
- title="Deploys now AND shuts the old instances down as soon as the new ones are up (overlap of 0)"
214
- onClick={() => {
215
- confirmNoOverlapDeploy(`Deploy All (${outdatedServices.length}), No Overlap`, () => {
216
- this.deployAll(outdatedServices, gitInfo.latestRef, true);
217
- });
218
- }}
219
- >
220
- <div>
221
- {bigEmoji("⚡")} <span>{this.state.isDeploying && "⏳ Deploying..." || `Deploy All (${outdatedServices.length}), No Overlap`}</span>
222
- </div>
223
- </button>
224
251
  </>}
225
252
  </>;
226
253
  }
@@ -415,20 +415,6 @@ export class MachineServiceControllerBase {
415
415
  void this.notifyMachines([], getConfigMachineIds(normalizeServiceConfig(serviceConfig)));
416
416
  }
417
417
 
418
- /** Cancels parameters that are scheduled to deploy (releaseTime in the future), reverting to what is currently live. Returns the cancelled config, so the caller can keep the edits (ex, back in the editor). */
419
- public async cancelScheduledDeploy(serviceId: string): Promise<ServiceConfig> {
420
- let record = await serviceConfigs.get(serviceId);
421
- if (!record) {
422
- throw new Error(`Service ${serviceId} does not exist`);
423
- }
424
- normalizeServiceConfig(record);
425
- if (!record.parameters.releaseTime || Date.now() >= record.parameters.releaseTime || !record.oldParameters) {
426
- throw new Error(`Service ${serviceId} has no scheduled deploy to cancel (it may have already gone live)`);
427
- }
428
- await serviceConfigs.set(serviceId, { ...record, parameters: record.oldParameters, oldParameters: undefined });
429
- void this.notifyMachines(getConfigMachineIds(record), []);
430
- return stripReleaseState(record);
431
- }
432
418
  public async getServiceConfigType(): Promise<string> {
433
419
  return extractType(module, "ServiceConfig");
434
420
  }
@@ -657,7 +643,6 @@ export const MachineServiceController = getSyncedController(
657
643
  setMachineConfig: {},
658
644
  addServiceConfig: {},
659
645
  setServiceConfigs: {},
660
- cancelScheduledDeploy: {},
661
646
  getServiceConfigType: {},
662
647
  deleteServiceConfig: {},
663
648
  getGitInfo: {},
@@ -682,7 +667,6 @@ export const MachineServiceController = getSyncedController(
682
667
  setMachineConfig: ["MachineConfig", "MachineConfigList"],
683
668
  addServiceConfig: ["ServiceConfig", "ServiceConfigList"],
684
669
  setServiceConfigs: ["ServiceConfig"],
685
- cancelScheduledDeploy: ["ServiceConfig"],
686
670
  deleteServiceConfig: ["ServiceConfig", "ServiceConfigList"],
687
671
  commitPushService: ["gitInfo", "ServiceConfig"],
688
672
  commitPushAndPublishQuerysub: ["gitInfo", "ServiceConfig"],