Merge pull request #14 from Start9Labs/feature/new-sdk

Feature/new sdk
This commit is contained in:
J H
2024-01-22 14:56:25 -07:00
committed by GitHub
3 changed files with 33 additions and 10 deletions

View File

@@ -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)),
),
)
},

View File

@@ -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 */

View File

@@ -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
},
}
},