@usine/server 0.3.0 → 0.4.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.
Files changed (226) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +22 -4
  3. package/dist/backend.d.ts +3 -1
  4. package/dist/backend.d.ts.map +1 -1
  5. package/dist/backend.js +5 -1
  6. package/dist/backend.js.map +1 -1
  7. package/dist/backup.d.ts +3 -3
  8. package/dist/backup.d.ts.map +1 -1
  9. package/dist/backup.js +3 -5
  10. package/dist/backup.js.map +1 -1
  11. package/dist/cli.d.ts +58 -5
  12. package/dist/cli.d.ts.map +1 -1
  13. package/dist/cli.js +216 -17
  14. package/dist/cli.js.map +1 -1
  15. package/dist/command.d.ts +22 -0
  16. package/dist/command.d.ts.map +1 -0
  17. package/dist/command.js +51 -0
  18. package/dist/command.js.map +1 -0
  19. package/dist/detach.d.ts +83 -0
  20. package/dist/detach.d.ts.map +1 -0
  21. package/dist/detach.js +320 -0
  22. package/dist/detach.js.map +1 -0
  23. package/dist/failure-message.d.ts +7 -1
  24. package/dist/failure-message.d.ts.map +1 -1
  25. package/dist/failure-message.js +71 -2
  26. package/dist/failure-message.js.map +1 -1
  27. package/dist/http.d.ts +14 -5
  28. package/dist/http.d.ts.map +1 -1
  29. package/dist/http.js +25 -13
  30. package/dist/http.js.map +1 -1
  31. package/dist/instance/environment.d.ts +17 -0
  32. package/dist/instance/environment.d.ts.map +1 -0
  33. package/dist/instance/environment.js +51 -0
  34. package/dist/instance/environment.js.map +1 -0
  35. package/dist/instance/id.d.ts +17 -0
  36. package/dist/instance/id.d.ts.map +1 -0
  37. package/dist/instance/id.js +35 -0
  38. package/dist/instance/id.js.map +1 -0
  39. package/dist/{instance-lock.d.ts → instance/lock.d.ts} +9 -5
  40. package/dist/instance/lock.d.ts.map +1 -0
  41. package/dist/instance/lock.js +127 -0
  42. package/dist/instance/lock.js.map +1 -0
  43. package/dist/instance/manifest.d.ts +52 -0
  44. package/dist/instance/manifest.d.ts.map +1 -0
  45. package/dist/instance/manifest.js +131 -0
  46. package/dist/instance/manifest.js.map +1 -0
  47. package/dist/instance/operator-api.d.ts +30 -0
  48. package/dist/instance/operator-api.d.ts.map +1 -0
  49. package/dist/instance/operator-api.js +47 -0
  50. package/dist/instance/operator-api.js.map +1 -0
  51. package/dist/instance/ports.d.ts +23 -0
  52. package/dist/instance/ports.d.ts.map +1 -0
  53. package/dist/instance/ports.js +81 -0
  54. package/dist/instance/ports.js.map +1 -0
  55. package/dist/instance/record.d.ts +82 -0
  56. package/dist/instance/record.d.ts.map +1 -0
  57. package/dist/instance/record.js +116 -0
  58. package/dist/instance/record.js.map +1 -0
  59. package/dist/instance/state.d.ts +45 -0
  60. package/dist/instance/state.d.ts.map +1 -0
  61. package/dist/instance/state.js +79 -0
  62. package/dist/instance/state.js.map +1 -0
  63. package/dist/instance/systemd.d.ts +36 -0
  64. package/dist/instance/systemd.d.ts.map +1 -0
  65. package/dist/instance/systemd.js +61 -0
  66. package/dist/instance/systemd.js.map +1 -0
  67. package/dist/logger.d.ts +3 -0
  68. package/dist/logger.d.ts.map +1 -0
  69. package/dist/logger.js +27 -0
  70. package/dist/logger.js.map +1 -0
  71. package/dist/main.js +35 -9
  72. package/dist/main.js.map +1 -1
  73. package/dist/registry.d.ts +20 -0
  74. package/dist/registry.d.ts.map +1 -0
  75. package/dist/registry.js +37 -0
  76. package/dist/registry.js.map +1 -0
  77. package/dist/restart.d.ts +19 -0
  78. package/dist/restart.d.ts.map +1 -0
  79. package/dist/restart.js +105 -0
  80. package/dist/restart.js.map +1 -0
  81. package/dist/status.d.ts +12 -0
  82. package/dist/status.d.ts.map +1 -0
  83. package/dist/status.js +99 -0
  84. package/dist/status.js.map +1 -0
  85. package/dist/stop.d.ts +81 -0
  86. package/dist/stop.d.ts.map +1 -0
  87. package/dist/stop.js +195 -0
  88. package/dist/stop.js.map +1 -0
  89. package/dist/system-sleep.d.ts +9 -0
  90. package/dist/system-sleep.d.ts.map +1 -0
  91. package/dist/system-sleep.js +42 -0
  92. package/dist/system-sleep.js.map +1 -0
  93. package/dist/tracing.d.ts +22 -0
  94. package/dist/tracing.d.ts.map +1 -0
  95. package/dist/tracing.js +61 -0
  96. package/dist/tracing.js.map +1 -0
  97. package/dist/up.d.ts +2 -2
  98. package/dist/up.d.ts.map +1 -1
  99. package/dist/up.js +41 -16
  100. package/dist/up.js.map +1 -1
  101. package/dist/upgrade.d.ts +58 -0
  102. package/dist/upgrade.d.ts.map +1 -0
  103. package/dist/upgrade.js +237 -0
  104. package/dist/upgrade.js.map +1 -0
  105. package/dist/web/assets/CompositeItem-DU6IyNMY.js +1 -0
  106. package/dist/web/assets/ToolbarRootContext-Cytu6o2e.js +1 -0
  107. package/dist/web/assets/X.es-B7iqdxa_.js +1 -0
  108. package/dist/web/assets/_agent-BVKD5odk.js +1 -0
  109. package/dist/web/assets/_loop-BFLzamuo.js +1 -0
  110. package/dist/web/assets/_name-Bh4AQ9sR.js +6 -0
  111. package/dist/web/assets/_name-CMVsmWzq.js +1 -0
  112. package/dist/web/assets/_name-DCkgEma_.js +1 -0
  113. package/dist/web/assets/_name-Ds_pWi15.js +1 -0
  114. package/dist/web/assets/_number-B9aYwvcQ.js +1 -0
  115. package/dist/web/assets/_run-BZWt47QS.js +8 -0
  116. package/dist/web/assets/_worker-Dgfufm5p.js +1 -0
  117. package/dist/web/assets/action-rCd1FeAz.js +1 -0
  118. package/dist/web/assets/agents-Drbg6qpH.js +1 -0
  119. package/dist/web/assets/agents-_6-dEjrY.js +1 -0
  120. package/dist/web/assets/button-DVWXde__.js +1 -0
  121. package/dist/web/assets/collapsible-IOhZV1qg.js +1 -0
  122. package/dist/web/assets/{core-BUmsKffF.js → core-wi-Hu_JV.js} +1 -1
  123. package/dist/web/assets/drawer-BiqnR_8i.js +1 -0
  124. package/dist/web/assets/dropdown-menu-C9D1kRkO.js +1 -0
  125. package/dist/web/assets/edit-and-retry-BgOR6mvP.js +1 -0
  126. package/dist/web/assets/error-alert-9tKpTE3v.js +1 -0
  127. package/dist/web/assets/file-error-SjG2jLJ9.js +1 -0
  128. package/dist/web/assets/fill-cell-ClM88KFD.js +1 -0
  129. package/dist/web/assets/heading-lX1a1LNN.js +1 -0
  130. package/dist/web/assets/index-BymNZU1Q.js +10 -0
  131. package/dist/web/assets/index-Dyjfp3ET.css +2 -0
  132. package/dist/web/assets/label-badge-aIGT1Bry.js +1 -0
  133. package/dist/web/assets/list-v8WJp2Eq.js +1 -0
  134. package/dist/web/assets/loops-BFoFf_og.js +1 -0
  135. package/dist/web/assets/mark-CC3RwMy_.js +1 -0
  136. package/dist/web/assets/{markdown-D07-JkYB.js → markdown-BnyfnuCL.js} +4 -4
  137. package/dist/web/assets/matchContext-BquevSJS.js +2 -0
  138. package/dist/web/assets/model-BerBT6R0.js +1 -0
  139. package/dist/web/assets/moves-Dg9sshX5.js +1 -0
  140. package/dist/web/assets/overview-C_tFKGZ8.js +1 -0
  141. package/dist/web/assets/page-DWnGi6wA.js +301 -0
  142. package/dist/web/assets/project-not-found-CodaBVdu.js +1 -0
  143. package/dist/web/assets/pull-request-marks-DE00nqGW.js +1 -0
  144. package/dist/web/assets/queries-B1SHA_r4.js +1 -0
  145. package/dist/web/assets/reload-Dsl0zjJ7.js +1 -0
  146. package/dist/web/assets/repositories-BdxmD192.js +1 -0
  147. package/dist/web/assets/repositories-D4wYJfa_.js +1 -0
  148. package/dist/web/assets/route-B_gphTYG.js +1 -0
  149. package/dist/web/assets/route-Cc7dKnn5.js +1 -0
  150. package/dist/web/assets/routes-BLy5TGH_.js +65 -0
  151. package/dist/web/assets/run-again-BTKagSXR.js +1 -0
  152. package/dist/web/assets/section-B3pWIIBa.js +1 -0
  153. package/dist/web/assets/section-CD-MB5r3.js +1 -0
  154. package/dist/web/assets/section-Id99HktI.js +1 -0
  155. package/dist/web/assets/settings-YrDysQXW.js +1 -0
  156. package/dist/web/assets/slots-BraHmbNr.js +1 -0
  157. package/dist/web/assets/status-badge-DnvNo1tG.js +1 -0
  158. package/dist/web/assets/strings-CW2XaR5f.js +1 -0
  159. package/dist/web/assets/table-BjyI4fVI.js +1 -0
  160. package/dist/web/assets/tasks-DCL8kLmD.js +1 -0
  161. package/dist/web/assets/transcript-sxRJzx6t.js +5 -0
  162. package/dist/web/assets/usage-CLQJdX9-.js +1 -0
  163. package/dist/web/assets/use-now-0P8TUXeg.js +1 -0
  164. package/dist/web/assets/useAnchoredPopupScrollLock-CQ83Wy-r.js +1 -0
  165. package/dist/web/assets/useNavigate-BW1WdocJ.js +1 -0
  166. package/dist/web/assets/usePositioner-rNCxnHO-.js +1 -0
  167. package/dist/web/assets/useTimeout-_TcdZXP6.js +1 -0
  168. package/dist/web/assets/with-selector-DoElmmtd.js +1 -0
  169. package/dist/web/assets/workers-BH5CBOR3.js +1 -0
  170. package/dist/web/index.html +15 -12
  171. package/package.json +16 -15
  172. package/dist/instance-lock.d.ts.map +0 -1
  173. package/dist/instance-lock.js +0 -58
  174. package/dist/instance-lock.js.map +0 -1
  175. package/dist/web/assets/DialogTitle-DrHlwOSg.js +0 -1
  176. package/dist/web/assets/_agent-cBqm12lE.js +0 -1
  177. package/dist/web/assets/_loop-kf1h3qkS.js +0 -1
  178. package/dist/web/assets/_name-CKWcxUh0.js +0 -2
  179. package/dist/web/assets/_name-DCEDRHnF.js +0 -1
  180. package/dist/web/assets/_name-sJkGyn7O.js +0 -1
  181. package/dist/web/assets/_number-DbgcVg1N.js +0 -1
  182. package/dist/web/assets/_run-DqslP0y6.js +0 -8
  183. package/dist/web/assets/_worker-CH4UoJT_.js +0 -1
  184. package/dist/web/assets/action-DYT048Jm.js +0 -1
  185. package/dist/web/assets/agents-DIZolb0U.js +0 -1
  186. package/dist/web/assets/agents-DMhSMb9O.js +0 -1
  187. package/dist/web/assets/button-C4yvcSko.js +0 -2
  188. package/dist/web/assets/copy-BM1l6IGB.js +0 -1
  189. package/dist/web/assets/error-alert-BrI00JbQ.js +0 -1
  190. package/dist/web/assets/file-error-C--_cWuj.js +0 -1
  191. package/dist/web/assets/index-BljdfRBm.js +0 -10
  192. package/dist/web/assets/index-YKcAk3No.css +0 -2
  193. package/dist/web/assets/item-rBBCTV8x.js +0 -1
  194. package/dist/web/assets/label-badge-ohqvZnY7.js +0 -1
  195. package/dist/web/assets/loops-CXM3f90o.js +0 -1
  196. package/dist/web/assets/loops-DWLXyUPN.js +0 -1
  197. package/dist/web/assets/moves-RiWgdCxQ.js +0 -5
  198. package/dist/web/assets/operator-copy-DsM7LJx6.js +0 -301
  199. package/dist/web/assets/outcome-YiIf6xbJ.js +0 -5
  200. package/dist/web/assets/project-not-found-CQVclgb0.js +0 -1
  201. package/dist/web/assets/query-DWN8IHdt.js +0 -1
  202. package/dist/web/assets/repositories-CoTEmYmS.js +0 -1
  203. package/dist/web/assets/repositories-Cq7zGzNb.js +0 -1
  204. package/dist/web/assets/rolldown-runtime-XKyaHtl9.js +0 -1
  205. package/dist/web/assets/route-CE9U74a9.js +0 -1
  206. package/dist/web/assets/route-DNH2EwHP.js +0 -1
  207. package/dist/web/assets/routes-XAUJJqfj.js +0 -1
  208. package/dist/web/assets/run-again-DxjFCuNu.js +0 -1
  209. package/dist/web/assets/run-drawer-CyjxH5mf.js +0 -1
  210. package/dist/web/assets/section-BBnBOk-U.js +0 -1
  211. package/dist/web/assets/section-Cm-j3zHs.js +0 -1
  212. package/dist/web/assets/section-DkBCDv4D.js +0 -1
  213. package/dist/web/assets/settings-iZf872O5.js +0 -1
  214. package/dist/web/assets/status-badge-CNlyvwWL.js +0 -1
  215. package/dist/web/assets/table-B6NH8hTW.js +0 -1
  216. package/dist/web/assets/tasks-DhLW-1gg.js +0 -1
  217. package/dist/web/assets/usage-DPUTTLGs.js +0 -1
  218. package/dist/web/assets/use-now-CcFZyFvf.js +0 -1
  219. package/dist/web/assets/useNavigate-lXd3v3E0.js +0 -1
  220. package/dist/web/assets/usePositioner-WErrA3Ah.js +0 -1
  221. package/dist/web/assets/useScrollLock-BOb01sL8.js +0 -1
  222. package/dist/web/assets/useTriggerFocusGuards-B0FItfLc.js +0 -1
  223. package/dist/web/assets/utils-BEQKLGgi.js +0 -1
  224. package/dist/web/assets/with-selector-NsM_5qXG.js +0 -1
  225. package/dist/web/assets/workers-BgocBXT9.js +0 -1
  226. package/dist/web/assets/workers-Dw2uHY0Y.js +0 -1
@@ -0,0 +1,37 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { runCommand } from "./command.js";
3
+ const NPM_VIEW_TIMEOUT = "30 seconds";
4
+ /** The registry has no version of the package that matches the spec, or npm couldn't ask it. */
5
+ export class PackageLookupError extends Schema.TaggedError("@usine/server/PackageLookupError")("PackageLookupError", {
6
+ name: Schema.String,
7
+ spec: Schema.String,
8
+ reason: Schema.String,
9
+ }) {
10
+ }
11
+ const Versions = Schema.fromJsonString(Schema.Union([Schema.String, Schema.Array(Schema.String)]));
12
+ const Dependencies = Schema.fromJsonString(Schema.Record(Schema.String, Schema.String));
13
+ /** Runs `npm view <name>@<spec> <field> --json` in `directory`, so its `.npmrc` applies. */
14
+ const npmView = (directory, name, spec, field) => runCommand("npm", ["view", `${name}@${spec}`, field, "--json"], directory, NPM_VIEW_TIMEOUT).pipe(Effect.map(({ stdout }) => stdout.trim()), Effect.mapError((error) => new PackageLookupError({ name, spec, reason: error.reason })));
15
+ /**
16
+ * Returns the version that `spec`, a version, range, or dist-tag, resolves to on the registry: the
17
+ * highest one for a range.
18
+ */
19
+ export const resolveVersion = Effect.fn("Registry.resolveVersion")(function* (directory, name, spec) {
20
+ yield* Effect.annotateCurrentSpan({ name, spec });
21
+ const output = yield* npmView(directory, name, spec, "version");
22
+ const decoded = yield* Schema.decodeUnknownEffect(Versions)(output).pipe(Effect.mapError(() => new PackageLookupError({ name, spec, reason: "no published version matches" })));
23
+ const versions = Schema.is(Schema.String)(decoded) ? [decoded] : decoded;
24
+ const version = versions.at(-1);
25
+ if (version === undefined) {
26
+ return yield* new PackageLookupError({ name, spec, reason: "no published version matches" });
27
+ }
28
+ return version;
29
+ });
30
+ /** Returns the published dependencies of `name@version`, with their version specs. */
31
+ export const dependenciesOf = Effect.fn("Registry.dependenciesOf")(function* (directory, name, version) {
32
+ const output = yield* npmView(directory, name, version, "dependencies");
33
+ if (output === "")
34
+ return {};
35
+ return yield* Schema.decodeUnknownEffect(Dependencies)(output).pipe(Effect.mapError((error) => new PackageLookupError({ name, spec: version, reason: error.message })));
36
+ });
37
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Effect } from "effect";
2
+ import { type CliEnvironment, type CliUsageError, type LifecycleOptions } from "./cli.ts";
3
+ import { type InstanceLaunch } from "./instance/record.ts";
4
+ import { InstanceNotRunningError, UnrecordedInstanceError } from "./stop.ts";
5
+ /**
6
+ * Returns the launch of a `usine up --detach` without flags from this CLI, which `usine restart`
7
+ * starts for an instance without a readable record.
8
+ */
9
+ export declare const fallbackLaunch: (environment: CliEnvironment) => Effect.Effect<InstanceLaunch, CliUsageError, never>;
10
+ /**
11
+ * Stops the `usine up` of the instance folder and starts it again in the background, with the
12
+ * Node.js binary, entry point, port, and flags that it recorded, or with `systemctl` if a systemd
13
+ * service runs it. Without a readable record, as from a usine version that writes only
14
+ * `.usine/instance.pid`, stops the process in that file and starts `fallback`. The checks then ask
15
+ * the port on which that process answers, and pass if none does. Fails with `ListeningPortsError`,
16
+ * before any signal, if the OS can't list that process's ports.
17
+ */
18
+ export declare const restart: (directory: string & import("effect/Brand").Brand<"InstanceDirectory">, options: LifecycleOptions, fallback: Effect.Effect<InstanceLaunch, CliUsageError, never>) => Effect.Effect<void, CliUsageError | import("./detach.ts").DetachedSpawnError | import("./detach.ts").DetachedStartError | import("./instance/lock.ts").InstanceLockError | InstanceNotRunningError | import("./stop.ts").KillTimeoutError | import("./instance/ports.ts").ListeningPortsError | import("./stop.ts").LiveAttemptsError | import("./stop.ts").MissingEnvironmentError | import("./instance/state.ts").SignalError | import("./stop.ts").StopTimeoutError | import("./instance/systemd.ts").SystemctlError | import("./detach.ts").SystemdStartError | UnrecordedInstanceError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient>;
19
+ //# sourceMappingURL=restart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../src/restart.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,MAAM,EAAU,MAAM,QAAQ,CAAC;AACjD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EAEtB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,KAAK,cAAc,EAIpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EAIxB,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAiB,cAAc,wDACM,CAAC;AA4FjE;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,43BAoBlB,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { Console, Effect, Option } from "effect";
2
+ import { environmentUp, } from "./cli.js";
3
+ import { startAgain, startedMessage } from "./detach.js";
4
+ import { listRuns } from "./instance/operator-api.js";
5
+ import { listeningPorts } from "./instance/ports.js";
6
+ import { currentLaunch, } from "./instance/record.js";
7
+ import { probeInstance } from "./instance/state.js";
8
+ import { supervisingUnit } from "./instance/systemd.js";
9
+ import { InstanceNotRunningError, UnrecordedInstanceError, refuseLiveAttempts, refuseMissingEnvironment, stopProcess, } from "./stop.js";
10
+ /**
11
+ * Returns the launch of a `usine up --detach` without flags from this CLI, which `usine restart`
12
+ * starts for an instance without a readable record.
13
+ */
14
+ export const fallbackLaunch = (environment) => environmentUp(environment).pipe(Effect.flatMap(currentLaunch));
15
+ /**
16
+ * Returns the port on which the process answers the operator API, or `None` if none of its ports
17
+ * does. Fails if the OS can't list its ports.
18
+ */
19
+ const operatorPort = Effect.fn("Cli.operatorPort")(function* (pid) {
20
+ const ports = yield* listeningPorts(pid);
21
+ const port = yield* Effect.findFirst(ports, (port) => listRuns(port).pipe(Effect.tapError((error) => Effect.logDebug("A port of the instance process doesn't answer the operator API", {
22
+ pid,
23
+ port,
24
+ reason: error.reason,
25
+ })), Effect.isSuccess));
26
+ yield* Effect.annotateCurrentSpan({ pid, ports, port: Option.getOrUndefined(port) });
27
+ return port;
28
+ });
29
+ /**
30
+ * Returns the process that `usine restart` stops, its record if readable, the systemd service that
31
+ * runs it, the port on which the checks ask it, and the next launch.
32
+ */
33
+ const restartTarget = Effect.fn("Cli.restartTarget")(function* (directory, fallback) {
34
+ yield* Effect.annotateCurrentSpan({ instanceDirectory: directory });
35
+ const state = yield* probeInstance(directory);
36
+ if (state._tag === "Stopped") {
37
+ yield* Effect.logInfo("Refusing to restart: usine is not running in the instance folder", {
38
+ instanceDirectory: directory,
39
+ });
40
+ return yield* new InstanceNotRunningError({ command: "restart", directory });
41
+ }
42
+ if (state._tag === "Running") {
43
+ const { record } = state;
44
+ yield* Effect.annotateCurrentSpan({ pid: record.pid });
45
+ return {
46
+ pid: record.pid,
47
+ record: Option.some(record),
48
+ unit: yield* supervisingUnit(record.pid, record.systemdUnit),
49
+ port: Option.some(record.launch.port),
50
+ launch: record.launch,
51
+ };
52
+ }
53
+ if (Option.isNone(state.pid)) {
54
+ yield* Effect.logInfo("Refusing to restart: a process holds the instance lock, but the pid file names no running process", { instanceDirectory: directory });
55
+ return yield* new UnrecordedInstanceError({ command: "restart", directory, pid: state.pid });
56
+ }
57
+ const pid = state.pid.value;
58
+ yield* Effect.annotateCurrentSpan({ pid });
59
+ const launch = yield* fallback;
60
+ const port = yield* operatorPort(pid).pipe(Effect.tapError((error) => Effect.logWarning("Refusing to restart: the ports of the instance process are unknown", {
61
+ pid,
62
+ reason: error.reason,
63
+ })));
64
+ yield* Effect.logInfo("Restarting an instance without a readable record with this CLI's launch", {
65
+ pid,
66
+ port: Option.getOrUndefined(port),
67
+ launchPort: launch.port,
68
+ script: launch.script,
69
+ });
70
+ yield* Console.log(Option.match(port, {
71
+ onNone: () => `usine (pid ${pid}) runs without a readable .usine/instance.json and answers on no port, so usine restart can't check its running attempts or gateway variables. usine restart starts usine up as usine up --detach would, on port ${launch.port}.`,
72
+ onSome: (current) => `usine (pid ${pid}) runs without a readable .usine/instance.json and answers on port ${current}. usine restart checks it there, then starts usine up as usine up --detach would, on port ${launch.port}.`,
73
+ }));
74
+ return {
75
+ pid,
76
+ record: Option.none(),
77
+ unit: Option.none(),
78
+ port,
79
+ launch,
80
+ };
81
+ });
82
+ /**
83
+ * Stops the `usine up` of the instance folder and starts it again in the background, with the
84
+ * Node.js binary, entry point, port, and flags that it recorded, or with `systemctl` if a systemd
85
+ * service runs it. Without a readable record, as from a usine version that writes only
86
+ * `.usine/instance.pid`, stops the process in that file and starts `fallback`. The checks then ask
87
+ * the port on which that process answers, and pass if none does. Fails with `ListeningPortsError`,
88
+ * before any signal, if the OS can't list that process's ports.
89
+ */
90
+ export const restart = Effect.fn("Cli.restart")(function* (directory, options, fallback) {
91
+ const { pid, record, unit, port, launch } = yield* restartTarget(directory, fallback);
92
+ if (Option.isSome(port)) {
93
+ yield* refuseMissingEnvironment("restart", port.value);
94
+ yield* refuseLiveAttempts("restart", port.value, options.force);
95
+ }
96
+ else {
97
+ yield* Effect.logWarning("Skipping the restart checks: the instance process answers on no port", {
98
+ pid,
99
+ });
100
+ }
101
+ yield* stopProcess("restart", pid, record, unit, options);
102
+ const started = yield* startAgain(directory, launch, unit, pid, options.timeout);
103
+ yield* Console.log(startedMessage(started));
104
+ });
105
+ //# sourceMappingURL=restart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restart.js","sourceRoot":"","sources":["../src/restart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Effect } from "effect";
2
+ /** What `usine status` prints, and whether a process holds the instance. */
3
+ export interface StatusReport {
4
+ readonly running: boolean;
5
+ readonly lines: ReadonlyArray<string>;
6
+ }
7
+ /**
8
+ * Reads whether `usine up` runs in the instance folder, with one request to its operator API and,
9
+ * for an engine installed from a pin, one `npm view`.
10
+ */
11
+ export declare const status: (directory: string & import("effect/Brand").Brand<"InstanceDirectory">) => Effect.Effect<StatusReport, import("./instance/lock.ts").InstanceLockError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient>;
12
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,MAAM,EAAU,MAAM,QAAQ,CAAC;AAgB5D,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC;AA+ID;;;GAGG;AACH,eAAO,MAAM,MAAM,iTAGjB,CAAC"}
package/dist/status.js ADDED
@@ -0,0 +1,99 @@
1
+ import { DateTime, Duration, Effect, Option } from "effect";
2
+ import { SERVER_HOST, packageVersion } from "./cli.js";
3
+ import { SERVER_PACKAGE, compareVersions, installedInInstance, readManifest, realPathOrSelf, serverPin, } from "./instance/manifest.js";
4
+ import { listRuns } from "./instance/operator-api.js";
5
+ import { probeInstance } from "./instance/state.js";
6
+ import { supervisingUnit } from "./instance/systemd.js";
7
+ import { resolveVersion } from "./registry.js";
8
+ /** The Run states that count as open, in lifecycle order from the latest. */
9
+ const OPEN_STATES = ["Running", "Queued", "Waiting", "Pending"];
10
+ const ago = (since, now) => {
11
+ const seconds = Math.max(0, Math.floor(Duration.toSeconds(DateTime.distance(since, now))));
12
+ return `${seconds === 0 ? "0s" : Duration.format(Duration.seconds(seconds))} ago`;
13
+ };
14
+ const field = (label, value) => ` ${label.padEnd(10)}${value}`;
15
+ /** Summarizes the open Runs by state, such as `2 running, 1 queued`. */
16
+ const openRuns = (runs) => {
17
+ const counts = OPEN_STATES.map((state) => [state, runs.filter((run) => run.state === state).length]).filter(([, count]) => count > 0);
18
+ return counts.length === 0
19
+ ? "none open"
20
+ : counts.map(([state, count]) => `${count} ${state.toLowerCase()}`).join(", ");
21
+ };
22
+ /**
23
+ * Returns the service line for an instance whose systemd service has it as its main process, or
24
+ * `None` for an instance outside one.
25
+ */
26
+ const serviceLine = (record) => supervisingUnit(record.pid, record.systemdUnit).pipe(Effect.map(Option.map((unit) => field("service", `${unit}, managed with systemctl`))), Effect.catchTag("SystemctlError", (error) => Effect.succeed(Option.some(field("service", `${error.unit}, unknown: ${error.reason}`)))));
27
+ /** Returns the update line for an engine installed from a pin, or `None` for other engines. */
28
+ const updateLine = Effect.fn("Cli.statusUpdate")(function* (directory, record, installed) {
29
+ if (!installed)
30
+ return Option.none();
31
+ const manifest = yield* readManifest(directory).pipe(Effect.tapError((error) => Effect.logWarning("Could not read the instance's package.json", {
32
+ path: error.path,
33
+ reason: error.reason,
34
+ })), Effect.orElseSucceed(() => Option.none()));
35
+ if (Option.isNone(Option.flatMap(manifest, serverPin)))
36
+ return Option.none();
37
+ return Option.some(yield* resolveVersion(directory, SERVER_PACKAGE, "latest").pipe(Effect.map((latest) => compareVersions(latest, record.version) > 0
38
+ ? field("update", `@usine/server ${latest} is available. Run usine upgrade.`)
39
+ : field("update", `none, ${record.version} is the latest release`)), Effect.catchTag("PackageLookupError", (error) => Effect.succeed(field("update", `unknown: ${error.reason}`)))));
40
+ });
41
+ const runningLines = Effect.fn("Cli.statusRunning")(function* (directory, record) {
42
+ const now = yield* DateTime.now;
43
+ const runs = yield* listRuns(record.launch.port).pipe(Effect.map(openRuns), Effect.catchTag("OperatorApiError", (error) => Effect.succeed(`unavailable: ${error.reason}`)));
44
+ const installed = installedInInstance(yield* realPathOrSelf(directory), yield* realPathOrSelf(record.launch.script));
45
+ const lines = [
46
+ record.stoppingSince === undefined
47
+ ? `usine is running in ${directory}.`
48
+ : `usine is stopping in ${directory}. Its drain started at ${DateTime.formatIso(record.stoppingSince)} (${ago(record.stoppingSince, now)}).`,
49
+ field("pid", String(record.pid)),
50
+ field("address", `http://${SERVER_HOST}:${record.launch.port}`),
51
+ ...Option.toArray(Option.map(record.launch.origin, (origin) => field("origin", origin))),
52
+ field("engine", `${SERVER_PACKAGE} ${record.version}, ${installed ? "installed in the instance" : `from ${record.launch.script}`}`),
53
+ field("started", `${DateTime.formatIso(record.startedAt)} (${ago(record.startedAt, now)})`),
54
+ ...Option.toArray(yield* serviceLine(record)),
55
+ field("runs", runs),
56
+ ];
57
+ // The same entry point at another version means that the install changed after the start.
58
+ if (process.argv[1] === record.launch.script) {
59
+ const version = yield* packageVersion().pipe(Effect.option);
60
+ if (Option.isSome(version) && version.value !== record.version) {
61
+ lines.push(field("installed", `${SERVER_PACKAGE} ${version.value}. Run usine restart to run it.`));
62
+ }
63
+ }
64
+ lines.push(...Option.toArray(yield* updateLine(directory, record, installed)));
65
+ return lines;
66
+ });
67
+ const reportOf = Effect.fn("Cli.statusReport")(function* (directory, state) {
68
+ switch (state._tag) {
69
+ case "Running":
70
+ return { running: true, lines: yield* runningLines(directory, state.record) };
71
+ case "Unrecorded":
72
+ return {
73
+ running: true,
74
+ lines: [
75
+ Option.match(state.pid, {
76
+ onNone: () => `A process holds .usine/instance.lock in ${directory}, but .usine/instance.pid names no running process.`,
77
+ onSome: (pid) => `usine is running in ${directory} with pid ${pid}, without .usine/instance.json. It is a usine version that doesn't write one, or it is still starting.`,
78
+ }),
79
+ ],
80
+ };
81
+ case "Stopped":
82
+ return {
83
+ running: false,
84
+ lines: [
85
+ `usine is not running in ${directory}.`,
86
+ ...Option.toArray(Option.map(state.stale, (pid) => field("stale", `pid ${pid} in .usine/ exited without removing its files. The next usine up replaces them.`))),
87
+ ],
88
+ };
89
+ }
90
+ });
91
+ /**
92
+ * Reads whether `usine up` runs in the instance folder, with one request to its operator API and,
93
+ * for an engine installed from a pin, one `npm view`.
94
+ */
95
+ export const status = Effect.fn("Cli.status")(function* (directory) {
96
+ const report = yield* reportOf(directory, yield* probeInstance(directory));
97
+ return report;
98
+ });
99
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"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"}
package/dist/stop.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import { Effect, Option, Schema } from "effect";
2
+ import type { LifecycleOptions } from "./cli.ts";
3
+ import { type InstanceRecord } from "./instance/record.ts";
4
+ /** The CLI command that stops the instance. */
5
+ export declare const LifecycleCommandName: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
6
+ export type LifecycleCommandName = typeof LifecycleCommandName.Type;
7
+ declare const StopTimeoutError_base: Schema.Class<StopTimeoutError, Schema.TaggedStruct<"StopTimeoutError", {
8
+ readonly command: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
9
+ readonly pid: Schema.brand<Schema.Int, "ProcessId">;
10
+ readonly timeout: Schema.Duration;
11
+ /** The Runs whose Attempts were live when the stop started. */
12
+ readonly runs: Schema.$Array<Schema.brand<Schema.NonEmptyString, "RunId">>;
13
+ /** The systemd service that runs the instance, which `systemctl start` starts again. */
14
+ readonly unit: Schema.Option<Schema.brand<Schema.String, "SystemdUnit">>;
15
+ }>, import("effect/Cause").YieldableError>;
16
+ /** The instance process didn't exit within the timeout. Its drain continues. */
17
+ export declare class StopTimeoutError extends StopTimeoutError_base {
18
+ }
19
+ declare const KillTimeoutError_base: Schema.Class<KillTimeoutError, Schema.TaggedStruct<"KillTimeoutError", {
20
+ readonly command: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
21
+ readonly pid: Schema.brand<Schema.Int, "ProcessId">;
22
+ readonly timeout: Schema.Duration;
23
+ }>, import("effect/Cause").YieldableError>;
24
+ /** The instance process still ran `timeout` after `--force` sent it `SIGKILL`. */
25
+ export declare class KillTimeoutError extends KillTimeoutError_base {
26
+ }
27
+ declare const InstanceNotRunningError_base: Schema.Class<InstanceNotRunningError, Schema.TaggedStruct<"InstanceNotRunningError", {
28
+ readonly command: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
29
+ readonly directory: Schema.String;
30
+ }>, import("effect/Cause").YieldableError>;
31
+ /** No `usine up` runs in the instance folder. */
32
+ export declare class InstanceNotRunningError extends InstanceNotRunningError_base {
33
+ }
34
+ declare const UnrecordedInstanceError_base: Schema.Class<UnrecordedInstanceError, Schema.TaggedStruct<"UnrecordedInstanceError", {
35
+ readonly command: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
36
+ readonly directory: Schema.String;
37
+ readonly pid: Schema.Option<Schema.brand<Schema.Int, "ProcessId">>;
38
+ }>, import("effect/Cause").YieldableError>;
39
+ /** A process holds the instance lock without an instance record, so its launch is unknown. */
40
+ export declare class UnrecordedInstanceError extends UnrecordedInstanceError_base {
41
+ }
42
+ declare const LiveAttemptsError_base: Schema.Class<LiveAttemptsError, Schema.TaggedStruct<"LiveAttemptsError", {
43
+ readonly command: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
44
+ readonly runs: Schema.$Array<Schema.brand<Schema.NonEmptyString, "RunId">>;
45
+ }>, import("effect/Cause").YieldableError>;
46
+ /** Runs have live Attempts, and the operator didn't pass `--force`. */
47
+ export declare class LiveAttemptsError extends LiveAttemptsError_base {
48
+ }
49
+ declare const MissingEnvironmentError_base: Schema.Class<MissingEnvironmentError, Schema.TaggedStruct<"MissingEnvironmentError", {
50
+ readonly command: Schema.Literals<readonly ["stop", "restart", "upgrade"]>;
51
+ readonly variables: Schema.$Array<Schema.NonEmptyString>;
52
+ }>, import("effect/Cause").YieldableError>;
53
+ /**
54
+ * Neither the shell that would start the new `usine up` nor `.env` sets variables that its startup
55
+ * needs.
56
+ */
57
+ export declare class MissingEnvironmentError extends MissingEnvironmentError_base {
58
+ }
59
+ /**
60
+ * Fails with `MissingEnvironmentError` if the current `ConfigProvider` lacks a gateway admin token
61
+ * variable of the instance that listens on `port`. The new `usine up` inherits this process's
62
+ * environment and reads the instance folder's `.env`, and doesn't start without them.
63
+ */
64
+ export declare const refuseMissingEnvironment: (command: "restart" | "stop" | "upgrade", port: number & import("effect/Brand").Brand<"ServerPort">) => Effect.Effect<undefined, MissingEnvironmentError, import("effect/http/HttpClient").HttpClient>;
65
+ /**
66
+ * Fails with `LiveAttemptsError` if a Run of the instance that listens on `port` has a live
67
+ * Attempt, unless `force` is set.
68
+ */
69
+ export declare const refuseLiveAttempts: (command: "restart" | "stop" | "upgrade", port: number & import("effect/Brand").Brand<"ServerPort">, force: boolean) => Effect.Effect<undefined, LiveAttemptsError, import("effect/http/HttpClient").HttpClient>;
70
+ /**
71
+ * Starts the drain of the instance process and waits for the process to exit: through
72
+ * `systemctl stop --no-block` if `unit` runs it, so that systemd doesn't restart it, else with
73
+ * `SIGTERM`. With `force`, sends a second `SIGTERM`, which ends the drain without waiting for
74
+ * running Attempts, and sends `SIGKILL` if the process still runs after the timeout. Doesn't repeat
75
+ * the first signal to a process that records that it is stopping.
76
+ */
77
+ export declare const stopProcess: (command: "restart" | "stop" | "upgrade", pid: number & import("effect/Brand").Brand<"ProcessId">, record: Option.Option<InstanceRecord>, unit: Option.Option<string & import("effect/Brand").Brand<"SystemdUnit">>, options: LifecycleOptions) => Effect.Effect<undefined, KillTimeoutError | import("./instance/state.ts").SignalError | StopTimeoutError | import("./instance/systemd.ts").SystemctlError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/http/HttpClient").HttpClient>;
78
+ /** Stops the `usine up` of the instance folder, and succeeds if none runs. */
79
+ export declare const stop: (directory: string & import("effect/Brand").Brand<"InstanceDirectory">, options: LifecycleOptions) => Effect.Effect<undefined, import("./instance/lock.ts").InstanceLockError | KillTimeoutError | import("./instance/state.ts").SignalError | StopTimeoutError | import("./instance/systemd.ts").SystemctlError | UnrecordedInstanceError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient>;
80
+ export {};
81
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../src/stop.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAQ,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,KAAK,cAAc,EAAa,MAAM,sBAAsB,CAAC;AAWtE,+CAA+C;AAC/C,eAAO,MAAM,oBAAoB,0DAAkD,CAAC;AACpF,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC,IAAI,CAAC;;;;;IASlE,+DAA+D;;IAE/D,wFAAwF;;;AAT1F,gFAAgF;AAChF,qBAAa,gBAAiB,SAAQ,qBAUpC;CAAG;;;;;;AAEL,kFAAkF;AAClF,qBAAa,gBAAiB,SAAQ,qBAMpC;CAAG;;;;;AAEL,iDAAiD;AACjD,qBAAa,uBAAwB,SAAQ,4BAE4C;CAAG;;;;;;AAE5F,8FAA8F;AAC9F,qBAAa,uBAAwB,SAAQ,4BAM3C;CAAG;;;;;AAEL,uEAAuE;AACvE,qBAAa,iBAAkB,SAAQ,sBAE6C;CAAG;;;;;AAEvF;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,4BAK3C;CAAG;AAEL;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,wMA0BnC,CAAC;AAeH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,kNAa7B,CAAC;AA+BH;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,+fAwDtB,CAAC;AAEH,8EAA8E;AAC9E,eAAO,MAAM,IAAI,seAkBf,CAAC"}
package/dist/stop.js ADDED
@@ -0,0 +1,195 @@
1
+ import { RunId } from "@usine/core/run";
2
+ import { Config, Console, Duration, Effect, Option, Schema } from "effect";
3
+ import { ProcessId } from "./instance/record.js";
4
+ import { gatewayTokenVariables, hasLiveAttempt, listRuns } from "./instance/operator-api.js";
5
+ import { probeInstance, processAlive, signalProcess } from "./instance/state.js";
6
+ import { SystemdUnit, supervisingUnit, systemctl } from "./instance/systemd.js";
7
+ const EXIT_POLL_INTERVAL = "200 millis";
8
+ /** Separates the two signals of `--force`, so that the OS doesn't merge them into one. */
9
+ const SECOND_SIGNAL_DELAY = "250 millis";
10
+ /** How long `--force` waits for the process to exit after `SIGKILL`. */
11
+ const KILL_EXIT_TIMEOUT = Duration.seconds(5);
12
+ /** The CLI command that stops the instance. */
13
+ export const LifecycleCommandName = Schema.Literals(["stop", "restart", "upgrade"]);
14
+ /** The instance process didn't exit within the timeout. Its drain continues. */
15
+ export class StopTimeoutError extends Schema.TaggedError("@usine/server/StopTimeoutError")("StopTimeoutError", {
16
+ command: LifecycleCommandName,
17
+ pid: ProcessId,
18
+ timeout: Schema.Duration,
19
+ /** The Runs whose Attempts were live when the stop started. */
20
+ runs: Schema.Array(RunId),
21
+ /** The systemd service that runs the instance, which `systemctl start` starts again. */
22
+ unit: Schema.Option(SystemdUnit),
23
+ }) {
24
+ }
25
+ /** The instance process still ran `timeout` after `--force` sent it `SIGKILL`. */
26
+ export class KillTimeoutError extends Schema.TaggedError("@usine/server/KillTimeoutError")("KillTimeoutError", {
27
+ command: LifecycleCommandName,
28
+ pid: ProcessId,
29
+ timeout: Schema.Duration,
30
+ }) {
31
+ }
32
+ /** No `usine up` runs in the instance folder. */
33
+ export class InstanceNotRunningError extends Schema.TaggedError("@usine/server/InstanceNotRunningError")("InstanceNotRunningError", { command: LifecycleCommandName, directory: Schema.String }) {
34
+ }
35
+ /** A process holds the instance lock without an instance record, so its launch is unknown. */
36
+ export class UnrecordedInstanceError extends Schema.TaggedError("@usine/server/UnrecordedInstanceError")("UnrecordedInstanceError", {
37
+ command: LifecycleCommandName,
38
+ directory: Schema.String,
39
+ pid: Schema.Option(ProcessId),
40
+ }) {
41
+ }
42
+ /** Runs have live Attempts, and the operator didn't pass `--force`. */
43
+ export class LiveAttemptsError extends Schema.TaggedError("@usine/server/LiveAttemptsError")("LiveAttemptsError", { command: LifecycleCommandName, runs: Schema.Array(RunId) }) {
44
+ }
45
+ /**
46
+ * Neither the shell that would start the new `usine up` nor `.env` sets variables that its startup
47
+ * needs.
48
+ */
49
+ export class MissingEnvironmentError extends Schema.TaggedError("@usine/server/MissingEnvironmentError")("MissingEnvironmentError", {
50
+ command: LifecycleCommandName,
51
+ variables: Schema.Array(Schema.NonEmptyString),
52
+ }) {
53
+ }
54
+ /**
55
+ * Fails with `MissingEnvironmentError` if the current `ConfigProvider` lacks a gateway admin token
56
+ * variable of the instance that listens on `port`. The new `usine up` inherits this process's
57
+ * environment and reads the instance folder's `.env`, and doesn't start without them.
58
+ */
59
+ export const refuseMissingEnvironment = Effect.fn("Cli.refuseMissingEnvironment")(function* (command, port) {
60
+ const names = yield* gatewayTokenVariables(port).pipe(Effect.tapError((error) => Effect.logWarning("Could not read the gateway token variables of the instance", {
61
+ url: error.url,
62
+ reason: error.reason,
63
+ })), Effect.orElseSucceed(() => []));
64
+ const missing = [];
65
+ for (const name of names) {
66
+ const value = yield* Config.option(Config.String(name)).pipe(Effect.orElseSucceed(() => Option.none()));
67
+ if (Option.isNone(value))
68
+ missing.push(name);
69
+ }
70
+ if (missing.length === 0)
71
+ return;
72
+ yield* Effect.logInfo("Refusing to stop the instance: the new process would lack variables", {
73
+ command,
74
+ variables: missing,
75
+ });
76
+ return yield* new MissingEnvironmentError({ command, variables: missing });
77
+ });
78
+ /** Returns the Runs with a live Attempt, or none if the operator API doesn't answer. */
79
+ const liveRuns = (port) => listRuns(port).pipe(Effect.map((runs) => runs.filter(hasLiveAttempt).map(({ id }) => id)), Effect.tapError((error) => Effect.logWarning("Could not list the running runs; the drain still waits for them", {
80
+ url: error.url,
81
+ reason: error.reason,
82
+ })), Effect.orElseSucceed(() => []));
83
+ /**
84
+ * Fails with `LiveAttemptsError` if a Run of the instance that listens on `port` has a live
85
+ * Attempt, unless `force` is set.
86
+ */
87
+ export const refuseLiveAttempts = Effect.fn("Cli.refuseLiveAttempts")(function* (command, port, force) {
88
+ if (force)
89
+ return;
90
+ const runs = yield* liveRuns(port);
91
+ if (runs.length === 0)
92
+ return;
93
+ yield* Effect.logInfo("Refusing to stop the instance while runs have live attempts", {
94
+ command,
95
+ runs,
96
+ });
97
+ return yield* new LiveAttemptsError({ command, runs });
98
+ });
99
+ /** Returns `true` once the process has exited, or `false` after `timeout`. */
100
+ const waitForExit = (pid, timeout) => Effect.gen(function* () {
101
+ while (yield* processAlive(pid))
102
+ yield* Effect.sleep(EXIT_POLL_INTERVAL);
103
+ }).pipe(Effect.timeoutOption(timeout), Effect.map(Option.isSome));
104
+ /**
105
+ * Sends `SIGKILL` to a process that a forced stop didn't end within `timeout`, and waits for it to
106
+ * exit.
107
+ */
108
+ const killProcess = Effect.fn("Cli.killProcess")(function* (command, pid, timeout) {
109
+ yield* Effect.annotateCurrentSpan({ command, pid });
110
+ yield* signalProcess(pid, "SIGKILL");
111
+ yield* Console.log(`usine (pid ${pid}) did not exit within ${Duration.format(timeout)}. Sent SIGKILL: the next start reattaches the running attempts.`);
112
+ if (yield* waitForExit(pid, KILL_EXIT_TIMEOUT))
113
+ return;
114
+ yield* Effect.logWarning("The instance process did not exit after SIGKILL", {
115
+ command,
116
+ pid,
117
+ timeoutSeconds: Duration.toSeconds(KILL_EXIT_TIMEOUT),
118
+ });
119
+ return yield* new KillTimeoutError({ command, pid, timeout: KILL_EXIT_TIMEOUT });
120
+ });
121
+ /**
122
+ * Starts the drain of the instance process and waits for the process to exit: through
123
+ * `systemctl stop --no-block` if `unit` runs it, so that systemd doesn't restart it, else with
124
+ * `SIGTERM`. With `force`, sends a second `SIGTERM`, which ends the drain without waiting for
125
+ * running Attempts, and sends `SIGKILL` if the process still runs after the timeout. Doesn't repeat
126
+ * the first signal to a process that records that it is stopping.
127
+ */
128
+ export const stopProcess = Effect.fn("Cli.stopProcess")(function* (command, pid, record, unit, options) {
129
+ yield* Effect.annotateCurrentSpan({
130
+ command,
131
+ pid,
132
+ force: options.force,
133
+ unit: Option.getOrUndefined(unit),
134
+ });
135
+ const stopping = Option.exists(record, ({ stoppingSince }) => stoppingSince !== undefined);
136
+ const runs = Option.isSome(record) ? yield* liveRuns(record.value.launch.port) : [];
137
+ if (stopping) {
138
+ yield* Console.log(`usine (pid ${pid}) is already stopping. Waiting for it to exit.`);
139
+ }
140
+ else if (Option.isSome(unit)) {
141
+ yield* Console.log(`Stopping usine (pid ${pid}) with systemctl stop ${unit.value}.`);
142
+ yield* systemctl(unit.value, ["stop", "--no-block"]);
143
+ yield* Effect.logInfo("Asked systemd to stop the instance's service", {
144
+ command,
145
+ pid,
146
+ unit: unit.value,
147
+ });
148
+ }
149
+ else {
150
+ yield* Console.log(`Stopping usine (pid ${pid}).`);
151
+ yield* signalProcess(pid, "SIGTERM");
152
+ }
153
+ if (options.force) {
154
+ yield* Effect.sleep(SECOND_SIGNAL_DELAY);
155
+ if (yield* processAlive(pid)) {
156
+ yield* signalProcess(pid, "SIGTERM");
157
+ yield* Console.log("Sent a second SIGTERM: usine stops without waiting for running attempts, and the next start reattaches them.");
158
+ }
159
+ }
160
+ else if (runs.length > 0) {
161
+ yield* Console.log(`Waiting for the running attempts of ${runs.length === 1 ? "run" : "runs"} ${runs.join(", ")} to end.`);
162
+ }
163
+ if (!(yield* waitForExit(pid, options.timeout))) {
164
+ yield* Effect.logWarning("The instance process did not exit before the timeout", {
165
+ command,
166
+ pid,
167
+ force: options.force,
168
+ timeoutSeconds: Duration.toSeconds(options.timeout),
169
+ });
170
+ if (!options.force) {
171
+ return yield* new StopTimeoutError({ command, pid, timeout: options.timeout, runs, unit });
172
+ }
173
+ yield* killProcess(command, pid, options.timeout);
174
+ }
175
+ yield* Effect.logInfo("The instance process exited", { command, pid });
176
+ yield* Console.log("usine stopped.");
177
+ });
178
+ /** Stops the `usine up` of the instance folder, and succeeds if none runs. */
179
+ export const stop = Effect.fn("Cli.stop")(function* (directory, options) {
180
+ const state = yield* probeInstance(directory);
181
+ if (state._tag === "Stopped") {
182
+ yield* Console.log(`usine is not running in ${directory}.`);
183
+ return;
184
+ }
185
+ if (state._tag === "Running") {
186
+ const { record } = state;
187
+ const unit = yield* supervisingUnit(record.pid, record.systemdUnit);
188
+ return yield* stopProcess("stop", record.pid, Option.some(record), unit, options);
189
+ }
190
+ if (Option.isNone(state.pid)) {
191
+ return yield* new UnrecordedInstanceError({ command: "stop", directory, pid: state.pid });
192
+ }
193
+ return yield* stopProcess("stop", state.pid.value, Option.none(), Option.none(), options);
194
+ });
195
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../src/stop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Effect } from "effect";
2
+ import { ChildProcessSpawner } from "effect/process";
3
+ /**
4
+ * Logs a warning if this Mac can sleep while `usine up` runs: system sleep is on, and `caffeinate`
5
+ * doesn't prevent it. A sleep closes the SSH connections to Workers and to the Gateway, and the
6
+ * orchestrator does nothing until the Mac wakes.
7
+ */
8
+ export declare const warnIfSystemSleeps: () => Effect.Effect<void, never, ChildProcessSpawner.ChildProcessSpawner>;
9
+ //# sourceMappingURL=system-sleep.d.ts.map