mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 02:11:56 +00:00
@@ -3,7 +3,12 @@ import { CheckResult } from "../health/checkFns"
|
||||
import { Trigger } from "../trigger"
|
||||
import { TriggerInput } from "../trigger/TriggerInput"
|
||||
import { defaultTrigger } from "../trigger/defaultTrigger"
|
||||
import { DaemonReturned, Effects, ValidIfNoStupidEscape } from "../types"
|
||||
import {
|
||||
DaemonReturned,
|
||||
Effects,
|
||||
Signals,
|
||||
ValidIfNoStupidEscape,
|
||||
} from "../types"
|
||||
import { createUtils } from "../util"
|
||||
type Daemon<Ids extends string, Command extends string, Id extends string> = {
|
||||
id: "" extends Id ? never : Id
|
||||
@@ -128,10 +133,10 @@ export class Daemons<Ids extends string> {
|
||||
})
|
||||
}
|
||||
return {
|
||||
async term() {
|
||||
async term(options?: { signal?: Signals; timeout?: number }) {
|
||||
await Promise.all(
|
||||
Object.values<Promise<DaemonReturned>>(daemonsStarted).map((x) =>
|
||||
x.then((x) => x.term()),
|
||||
x.then((x) => x.term(options)),
|
||||
),
|
||||
)
|
||||
},
|
||||
|
||||
12
lib/types.ts
12
lib/types.ts
@@ -5,6 +5,8 @@ import { PortOptions } from "./interfaces/Host"
|
||||
import { UrlString } from "./util/getNetworkInterface"
|
||||
import { NetworkInterfaceType } from "./util/utils"
|
||||
|
||||
export type Signals = "SIGINT" | "SIGTERM" | "SIGKILL" | "SIGHUP"
|
||||
|
||||
export type ExportedAction = (options: {
|
||||
effects: Effects
|
||||
input?: Record<string, unknown>
|
||||
@@ -128,7 +130,7 @@ export type DaemonReceipt = {
|
||||
}
|
||||
export type Daemon = {
|
||||
wait(): Promise<string>
|
||||
term(): Promise<void>
|
||||
term(options?: { signal?: Signals; timeout?: number }): Promise<void>
|
||||
[DaemonProof]: never
|
||||
}
|
||||
|
||||
@@ -148,7 +150,7 @@ export type CommandType<A extends string> =
|
||||
|
||||
export type DaemonReturned = {
|
||||
wait(): Promise<string>
|
||||
term(): Promise<void>
|
||||
term(options?: { signal?: Signals; timeout?: number }): Promise<void>
|
||||
}
|
||||
|
||||
export type ActionMetadata = {
|
||||
@@ -222,12 +224,10 @@ export type ExposeUiPaths<Store> = Array<{
|
||||
export type Effects = {
|
||||
executeAction<Input>(opts: {
|
||||
serviceId?: string
|
||||
actionId: string
|
||||
input: Input
|
||||
}): Promise<unknown>
|
||||
|
||||
/** Sandbox mode lets us read but not write */
|
||||
is_sandboxed(): Promise<boolean>
|
||||
|
||||
/** Removes all network bindings */
|
||||
clearBindings(): Promise<void>
|
||||
/** Creates a host connected to the specified port with the provided options */
|
||||
@@ -397,6 +397,8 @@ export type Effects = {
|
||||
message?: string
|
||||
}): 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 */
|
||||
setDependencies(dependencies: Dependencies): Promise<DependenciesReceipt>
|
||||
/** Exists could be useful during the runtime to know if some service exists, option dep */
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
ExtractStore,
|
||||
InterfaceId,
|
||||
PackageId,
|
||||
Signals,
|
||||
ValidIfNoStupidEscape,
|
||||
} from "../types"
|
||||
import { GetSystemSmtp } from "./GetSystemSmtp"
|
||||
@@ -38,6 +39,10 @@ import * as CP from "node:child_process"
|
||||
import { promisify } from "node:util"
|
||||
import { splitCommand } from "./splitCommand"
|
||||
|
||||
export const SIGTERM: Signals = "SIGTERM"
|
||||
export const SIGKILL: Signals = "SIGTERM"
|
||||
export const NO_TIMEOUT = -1
|
||||
|
||||
const childProcess = {
|
||||
exec: promisify(CP.exec),
|
||||
execFile: promisify(CP.execFile),
|
||||
@@ -204,8 +209,19 @@ export const utils = <Store = never, WrapperOverWrite = { const: never }>(
|
||||
wait() {
|
||||
return answer
|
||||
},
|
||||
async term() {
|
||||
childProcess.kill()
|
||||
async term({ signal = SIGTERM, timeout = NO_TIMEOUT } = {}) {
|
||||
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
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user