sliftutils 1.7.14 → 1.7.15

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/index.d.ts CHANGED
@@ -223,7 +223,7 @@ declare module "sliftutils/misc/https/hostServer" {
223
223
  setDNSRecord?: boolean;
224
224
  publicIp?: string;
225
225
  allowHostnames?: string[];
226
- /** Deploy takeover: when the port is busy (the previous version still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). Only pass this when a deploy timeline actually exists; without it a busy port is a real misconfiguration and must throw. */
226
+ /** When the port is busy (e.g. the previous deploy still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). */
227
227
  portFallback?: {
228
228
  /** Delay until the next main-port acquisition attempt (tightened around the predecessor's scheduled death) */
229
229
  getAcquireDelay: () => number;
@@ -3273,14 +3273,14 @@ declare module "sliftutils/storage/remoteStorage/createArchives" {
3273
3273
  declare module "sliftutils/storage/remoteStorage/deployTakeover" {
3274
3274
  import { RemoteConfig } from "../IArchives";
3275
3275
  export type TakeoverEvent = "remapChanged" | "diskScan";
3276
- /** Starts the takeover machinery. Returns whether a deploy timeline exists - when it doesn't,
3277
- * everything here stays inert (and the caller must NOT fall back to alternate ports, since a busy
3278
- * port then means a real misconfiguration, not a deploy). */
3276
+ /** Starts the takeover machinery. Port fallback (alternate port + registry + acquisition polling)
3277
+ * works regardless; without a deploy timeline folder the switchover-specific parts (the remap,
3278
+ * the flush deadline, the tighter acquisition pacing) simply stay inert. */
3279
3279
  export declare function initDeployTakeover(config: {
3280
3280
  domain: string;
3281
3281
  mainPort: number;
3282
3282
  storageFolder: string;
3283
- }): Promise<boolean>;
3283
+ }): Promise<void>;
3284
3284
  /** Called when we had to listen on an alternate port (the main port was still held by our
3285
3285
  * predecessor): registers it so the predecessor can route the middle overlap window to us. */
3286
3286
  export declare function registerAltPort(port: number): Promise<void>;
@@ -6,7 +6,7 @@ export type HostServerConfig = {
6
6
  setDNSRecord?: boolean;
7
7
  publicIp?: string;
8
8
  allowHostnames?: string[];
9
- /** Deploy takeover: when the port is busy (the previous version still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). Only pass this when a deploy timeline actually exists; without it a busy port is a real misconfiguration and must throw. */
9
+ /** When the port is busy (e.g. the previous deploy still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). */
10
10
  portFallback?: {
11
11
  /** Delay until the next main-port acquisition attempt (tightened around the predecessor's scheduled death) */
12
12
  getAcquireDelay: () => number;
@@ -32,7 +32,7 @@ export type HostServerConfig = {
32
32
  setDNSRecord?: boolean;
33
33
  publicIp?: string;
34
34
  allowHostnames?: string[];
35
- /** Deploy takeover: when the port is busy (the previous version still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). Only pass this when a deploy timeline actually exists; without it a busy port is a real misconfiguration and must throw. */
35
+ /** When the port is busy (e.g. the previous deploy still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). */
36
36
  portFallback?: {
37
37
  /** Delay until the next main-port acquisition attempt (tightened around the predecessor's scheduled death) */
38
38
  getAcquireDelay: () => number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.14",
3
+ "version": "1.7.15",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -1,13 +1,13 @@
1
1
  import { RemoteConfig } from "../IArchives";
2
2
  export type TakeoverEvent = "remapChanged" | "diskScan";
3
- /** Starts the takeover machinery. Returns whether a deploy timeline exists - when it doesn't,
4
- * everything here stays inert (and the caller must NOT fall back to alternate ports, since a busy
5
- * port then means a real misconfiguration, not a deploy). */
3
+ /** Starts the takeover machinery. Port fallback (alternate port + registry + acquisition polling)
4
+ * works regardless; without a deploy timeline folder the switchover-specific parts (the remap,
5
+ * the flush deadline, the tighter acquisition pacing) simply stay inert. */
6
6
  export declare function initDeployTakeover(config: {
7
7
  domain: string;
8
8
  mainPort: number;
9
9
  storageFolder: string;
10
- }): Promise<boolean>;
10
+ }): Promise<void>;
11
11
  /** Called when we had to listen on an alternate port (the main port was still held by our
12
12
  * predecessor): registers it so the predecessor can route the middle overlap window to us. */
13
13
  export declare function registerAltPort(port: number): Promise<void>;
@@ -273,20 +273,19 @@ async function recompute(): Promise<void> {
273
273
  emit("remapChanged");
274
274
  }
275
275
 
276
- /** Starts the takeover machinery. Returns whether a deploy timeline exists - when it doesn't,
277
- * everything here stays inert (and the caller must NOT fall back to alternate ports, since a busy
278
- * port then means a real misconfiguration, not a deploy). */
279
- export async function initDeployTakeover(config: { domain: string; mainPort: number; storageFolder: string }): Promise<boolean> {
276
+ /** Starts the takeover machinery. Port fallback (alternate port + registry + acquisition polling)
277
+ * works regardless; without a deploy timeline folder the switchover-specific parts (the remap,
278
+ * the flush deadline, the tighter acquisition pacing) simply stay inert. */
279
+ export async function initDeployTakeover(config: { domain: string; mainPort: number; storageFolder: string }): Promise<void> {
280
280
  initialized = config;
281
281
  ancestorPids = await getAncestorPids();
282
282
  timelineFolder = await findTimelineFolder();
283
- if (!timelineFolder) return false;
283
+ if (!timelineFolder) return;
284
284
  await recompute();
285
285
  let poll = setInterval(() => {
286
286
  void recompute().catch((e: Error) => console.error(`Deploy takeover recompute failed: ${e.stack ?? e}`));
287
287
  }, TIMELINE_POLL_INTERVAL);
288
288
  (poll as { unref?: () => void }).unref?.();
289
- return true;
290
289
  }
291
290
 
292
291
  /** Called when we had to listen on an alternate port (the main port was still held by our
@@ -119,21 +119,22 @@ export async function hostStorageServer(config: HostStorageServerConfig): Promis
119
119
  }, DISK_SPACE_CHECK_INTERVAL_MS);
120
120
  (interval as { unref?: () => void }).unref?.();
121
121
 
122
- // Zero-downtime deploys: only enabled when a deploy timeline exists - otherwise a busy port is
123
- // a real misconfiguration and must throw, not silently listen elsewhere
124
- let hasDeployTimeline = await initDeployTakeover({ domain, mainPort: port, storageFolder: path.resolve(folder) });
122
+ // Port fallback is always on: a busy port means listening on an alternate, registering it, and
123
+ // polling to take the real port. The deploy takeover machinery merely rides on top (tighter
124
+ // polling around a scheduled switchover, and the valid-window remap once a successor is known).
125
+ await initDeployTakeover({ domain, mainPort: port, storageFolder: path.resolve(folder) });
125
126
 
126
127
  await hostServer({
127
128
  domain,
128
129
  port,
129
130
  setDNSRecord: true,
130
- portFallback: hasDeployTimeline && {
131
+ portFallback: {
131
132
  getAcquireDelay: getMainPortAcquireDelay,
132
133
  onListening: (listeningPort, isMainPort) => {
133
134
  if (isMainPort) return;
134
135
  addExtraListenPort(listeningPort);
135
136
  void registerAltPort(listeningPort).catch((e: Error) => console.error(`Registering alternate port ${listeningPort} failed: ${e.stack ?? e}`));
136
137
  },
137
- } || undefined,
138
+ },
138
139
  });
139
140
  }