feat: Add in the new changes for the new init system that is going to be used in the startos

This commit is contained in:
J H
2023-11-28 13:15:15 -07:00
parent 27127f58d4
commit 125c7a2ac3
3 changed files with 32 additions and 7 deletions

View File

@@ -3,7 +3,12 @@ import { CheckResult } from "../health/checkFns"
import { Trigger } from "../trigger" import { Trigger } from "../trigger"
import { TriggerInput } from "../trigger/TriggerInput" import { TriggerInput } from "../trigger/TriggerInput"
import { defaultTrigger } from "../trigger/defaultTrigger" import { defaultTrigger } from "../trigger/defaultTrigger"
import { DaemonReturned, Effects, ValidIfNoStupidEscape } from "../types" import {
DaemonReturned,
Effects,
Signals,
ValidIfNoStupidEscape,
} from "../types"
import { createUtils } from "../util" import { createUtils } from "../util"
type Daemon<Ids extends string, Command extends string, Id extends string> = { type Daemon<Ids extends string, Command extends string, Id extends string> = {
id: "" extends Id ? never : Id id: "" extends Id ? never : Id
@@ -128,10 +133,10 @@ export class Daemons<Ids extends string> {
}) })
} }
return { return {
async term() { async term(options?: { signal?: Signals; timeout?: number }) {
await Promise.all( await Promise.all(
Object.values<Promise<DaemonReturned>>(daemonsStarted).map((x) => Object.values<Promise<DaemonReturned>>(daemonsStarted).map((x) =>
x.then((x) => x.term()), x.then((x) => x.term(options)),
), ),
) )
}, },

View File

@@ -5,6 +5,8 @@ import { PortOptions } from "./interfaces/Host"
import { UrlString } from "./util/getNetworkInterface" import { UrlString } from "./util/getNetworkInterface"
import { NetworkInterfaceType } from "./util/utils" import { NetworkInterfaceType } from "./util/utils"
export type Signals = "SIGINT" | "SIGTERM" | "SIGKILL" | "SIGHUP"
export type ExportedAction = (options: { export type ExportedAction = (options: {
effects: Effects effects: Effects
input?: Record<string, unknown> input?: Record<string, unknown>
@@ -128,7 +130,7 @@ export type DaemonReceipt = {
} }
export type Daemon = { export type Daemon = {
wait(): Promise<string> wait(): Promise<string>
term(): Promise<void> term(options?: { signal?: Signals; timeout?: number }): Promise<void>
[DaemonProof]: never [DaemonProof]: never
} }
@@ -148,7 +150,7 @@ export type CommandType<A extends string> =
export type DaemonReturned = { export type DaemonReturned = {
wait(): Promise<string> wait(): Promise<string>
term(): Promise<void> term(options?: { signal?: Signals; timeout?: number }): Promise<void>
} }
export type ActionMetadata = { export type ActionMetadata = {
@@ -398,6 +400,8 @@ export type Effects = {
message?: string message?: string
}): Promise<void> }): Promise<void>
setMainStatus(o: { status: "running" | "stopped" }): Promise<void>
/** Set the dependencies of what the service needs, usually ran during the set config as a best practice */ /** Set the dependencies of what the service needs, usually ran during the set config as a best practice */
setDependencies(dependencies: Dependencies): Promise<DependenciesReceipt> setDependencies(dependencies: Dependencies): Promise<DependenciesReceipt>
/** Exists could be useful during the runtime to know if some service exists, option dep */ /** Exists could be useful during the runtime to know if some service exists, option dep */

View File

@@ -11,6 +11,7 @@ import {
ExtractStore, ExtractStore,
InterfaceId, InterfaceId,
PackageId, PackageId,
Signals,
ValidIfNoStupidEscape, ValidIfNoStupidEscape,
} from "../types" } from "../types"
import { GetSystemSmtp } from "./GetSystemSmtp" import { GetSystemSmtp } from "./GetSystemSmtp"
@@ -38,6 +39,10 @@ import * as CP from "node:child_process"
import { promisify } from "node:util" import { promisify } from "node:util"
import { splitCommand } from "./splitCommand" import { splitCommand } from "./splitCommand"
export const SIGTERM: Signals = "SIGTERM"
export const SIGKILL: Signals = "SIGTERM"
export const NO_TIMEOUT = -1
const childProcess = { const childProcess = {
exec: promisify(CP.exec), exec: promisify(CP.exec),
execFile: promisify(CP.execFile), execFile: promisify(CP.execFile),
@@ -204,8 +209,19 @@ export const utils = <Store = never, WrapperOverWrite = { const: never }>(
wait() { wait() {
return answer return answer
}, },
async term() { async term({ signal = SIGTERM, timeout = NO_TIMEOUT } = {}) {
childProcess.kill() childProcess.kill(signal)
if (timeout <= NO_TIMEOUT) {
const didTimeout = await Promise.race([
new Promise((resolve) => setTimeout(resolve, timeout)).then(
() => true,
),
answer.then(() => false),
])
if (didTimeout) childProcess.kill(SIGKILL)
}
await answer
}, },
} }
}, },