querysub 0.581.0 → 0.583.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.581.0",
3
+ "version": "0.583.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",
@@ -71,7 +71,7 @@
71
71
  "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
72
72
  "pako": "^2.1.0",
73
73
  "peggy": "^5.0.6",
74
- "sliftutils": "^1.7.50",
74
+ "sliftutils": "^1.7.53",
75
75
  "socket-function": "^1.2.26",
76
76
  "terser": "^5.31.0",
77
77
  "typenode": "^6.6.1",
@@ -28,7 +28,8 @@ const PAST_COLOR = { h: 0, s: 0, l: 90 };
28
28
  const FUTURE_COLOR = { h: 45, s: 80, l: 85 };
29
29
  // Windows are days or hours wide, so the countdown only has to be roughly right
30
30
  const TIME_REFRESH_INTERVAL = 60 * 1000;
31
- const WATCH_POLL_INTERVAL = 60 * 1000;
31
+ // Watching exists to see a config change as it happens - a deploy or a server disagreeing with the others - so it polls far faster than the window countdowns need to update
32
+ const WATCH_POLL_INTERVAL = 5 * 1000;
32
33
  const WATCH_ACTIVE_COLOR = { h: 195, s: 60, l: 85 };
33
34
  const WINDOW_HEADER_SIZE = 13;
34
35
  const WINDOW_TIME_SIZE = 14;
@@ -513,7 +514,8 @@ class RouteConfigGroupView extends qreact.Component<{ group: RouteConfigGroup }>
513
514
  class LiveWatchView extends qreact.Component<{ watchKey: string; watch: LiveWatch }> {
514
515
  render() {
515
516
  let { watchKey, watch } = this.props;
516
- let now = Querysub.timeDelayed(TIME_REFRESH_INTERVAL);
517
+ // Ticks with the polling, not with the window countdowns - "updated 1 minute ago" on something refreshed seconds ago reads as broken
518
+ let now = Querysub.timeDelayed(WATCH_POLL_INTERVAL);
517
519
  let sources = (watch.routing?.sources || []).map(normalizeSource);
518
520
  return <div className={css.vbox(10).fillWidth.pad2(10, 8).bord2(WATCH_ACTIVE_COLOR.h, WATCH_ACTIVE_COLOR.s, WATCH_ACTIVE_COLOR.l - 25)}>
519
521
  <div className={css.hbox(8).wrap.fontSize(WINDOW_HEADER_SIZE)}>
@@ -17,7 +17,7 @@ import { getPathStr2 } from "../../path";
17
17
  import { ATag, Anchor } from "../../library-components/ATag";
18
18
  import { ScrollOnMount } from "../../library-components/ScrollOnMount";
19
19
  import { PrimitiveDisplay } from "../../diagnostics/logs/ObjectDisplay";
20
- import { RenderGitRefInfo, UpdateServiceButtons, bigEmoji, buttonStyle } from "./deployButtons";
20
+ import { RenderGitRefInfo, UpdateServiceButtons, bigEmoji, buttonStyle, confirmNoOverlapDeploy } from "./deployButtons";
21
21
  import { TypedConfigEditor } from "../../library-components/TypedConfigEditor";
22
22
  import { managementPageURL } from "../../diagnostics/managementPages";
23
23
  import { getLogViewerParams } from "../../diagnostics/logs/IndexedLogs/LogViewerParams";
@@ -645,7 +645,9 @@ export class ServiceDetailPage extends qreact.Component {
645
645
  disabled={this.state.isDeploying}
646
646
  title="Deploys now AND shuts the old instances down as soon as the new ones are up (overlap of 0)"
647
647
  onClick={() => {
648
- this.deployConfig(makeDeployConfig(0));
648
+ confirmNoOverlapDeploy("Deploy, No Overlap", () => {
649
+ this.deployConfig(makeDeployConfig(0));
650
+ });
649
651
  }}>
650
652
  Deploy, No Overlap
651
653
  </button>
@@ -12,6 +12,7 @@ import { MachineController } from "../machineController";
12
12
  import { deepCloneJSON } from "socket-function/src/misc";
13
13
  import { unique } from "../../misc";
14
14
  import { CommitModal } from "./CommitModal";
15
+ import { closeAllModals } from "../../5-diagnostics/Modal";
15
16
 
16
17
  module.hotreload = true;
17
18
 
@@ -71,6 +72,40 @@ export class RenderGitRefInfo extends qreact.Component<{
71
72
 
72
73
  export const buttonStyle = css.pad2(12, 8).button.bord2(0, 0, 20).fontWeight("bold").vbox(2).alignItems("center");
73
74
 
75
+ /** Confirms a no-overlap deploy. It is worth interrupting for because the thing it buys is smaller than it looks: the old instances still get their shutdown while the new ones are up, so it trades minutes of overlap for seconds of it rather than removing overlap at all. */
76
+ class NoOverlapConfirmModal extends qreact.Component<{ actionLabel: string; onConfirm: () => void }> {
77
+ render() {
78
+ return <div className={css.vbox(14).maxWidth(560)}>
79
+ <div className={css.fontSize(18).boldStyle}>Shut the old instances down immediately?</div>
80
+ <div>
81
+ This does not give you a clean cut over. The new instances are already up before the old ones are told to stop, and stopping is not instant, so there is still a few seconds of overlap either way.
82
+ </div>
83
+ <div>
84
+ Since the overlap cannot be avoided, deploying normally — and letting the old instances run for {formatTime(DEFAULT_OVERLAP_TIME)} — is usually the better choice.
85
+ </div>
86
+ <div className={css.hbox(10)}>
87
+ <button
88
+ className={buttonStyle.hsl(0, 85, 70)}
89
+ onClick={() => {
90
+ closeAllModals();
91
+ this.props.onConfirm();
92
+ }}
93
+ >
94
+ {this.props.actionLabel}
95
+ </button>
96
+ <button className={buttonStyle.hsl(0, 0, 90)} onClick={() => closeAllModals()}>
97
+ Cancel
98
+ </button>
99
+ </div>
100
+ </div>;
101
+ }
102
+ }
103
+ export function confirmNoOverlapDeploy(actionLabel: string, onConfirm: () => void) {
104
+ showFullscreenModal({
105
+ content: <NoOverlapConfirmModal actionLabel={actionLabel} onConfirm={onConfirm} />,
106
+ });
107
+ }
108
+
74
109
  export class UpdateButtons extends qreact.Component<{
75
110
  services: ServiceConfig[];
76
111
  }> {
@@ -178,7 +213,9 @@ export class UpdateButtons extends qreact.Component<{
178
213
  disabled={this.state.isDeploying}
179
214
  title="Deploys now AND shuts the old instances down as soon as the new ones are up (overlap of 0)"
180
215
  onClick={() => {
181
- this.deployAll(outdatedServices, gitInfo.latestRef, true);
216
+ confirmNoOverlapDeploy(`Deploy All (${outdatedServices.length}), No Overlap`, () => {
217
+ this.deployAll(outdatedServices, gitInfo.latestRef, true);
218
+ });
182
219
  }}
183
220
  >
184
221
  <div>
@@ -250,7 +287,9 @@ export class UpdateServiceButtons extends qreact.Component<{
250
287
  disabled={this.state.isDeploying}
251
288
  title="Deploys now AND shuts the old instances down as soon as the new ones are up (overlap of 0)"
252
289
  onClick={() => {
253
- this.deploy(gitInfo.latestRef, true);
290
+ confirmNoOverlapDeploy("Update to New, No Overlap", () => {
291
+ this.deploy(gitInfo.latestRef, true);
292
+ });
254
293
  }}
255
294
  >
256
295
  <div>