Skip to content

Commit

Permalink
WIP support for Node and Bun
Browse files Browse the repository at this point in the history
  • Loading branch information
Hexagon committed May 16, 2024
1 parent ce3b829 commit 36b6c35
Show file tree
Hide file tree
Showing 20 changed files with 259 additions and 122 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ coverage
_site

# Node files
.npmrc
package-lock.json
package.json
node_modules

# VSCode files
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@jsr:registry=https://npm.jsr.io
4 changes: 2 additions & 2 deletions application.meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@

const Application = {
name: "pup",
version: "1.0.0-rc.39",
version: "1.0.0-rc.40",
url: "jsr:@pup/pup@$VERSION",
canary_url: "https://raw.githubusercontent.com/Hexagon/pup/main/pup.ts",
deno: null, /* Minimum stable version of Deno required to run Pup (without --unstable-* flags) */
deno: "1.43.0", /* Minimum stable version of Deno required to run Pup (without --unstable-* flags) */
deno_unstable: "1.43.0", /* Minimum version of Deno required to run Pup (with --unstable-* flags) */
repository: "https://github.com/hexagon/pup",
changelog: "https://hexagon.github.io/pup/changelog.html",
Expand Down
9 changes: 3 additions & 6 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
"./lib": "./mod.ts"
},

"unstable": [
"kv"
],

"fmt": {
"lineWidth": 200,
"semiColons": false,
Expand All @@ -30,7 +26,7 @@

"tasks": {
"update-deps": "deno run --allow-read=. --allow-net=jsr.io,registry.npmjs.org jsr:@check/deps",
"check": "deno fmt --check && deno lint && deno check --unstable-kv pup.ts && deno test --allow-read --allow-write --allow-env --allow-net --allow-sys --allow-run --unstable-kv --coverage=cov_profile && echo \"Generating coverage\" && deno coverage cov_profile --exclude=pup/test --lcov --output=cov_profile.lcov",
"check": "deno fmt --check && deno lint && deno check pup.ts && deno test --allow-read --allow-write --allow-env --allow-net --allow-sys --allow-run --coverage=cov_profile && echo \"Generating coverage\" && deno coverage cov_profile --exclude=pup/test --lcov --output=cov_profile.lcov",
"check-coverage": "deno task check && genhtml cov_profile.lcov --output-directory cov_profile/html && lcov --list cov_profile.lcov && deno run --allow-net --allow-read https://deno.land/std/http/file_server.ts cov_profile/html",
"build-schema": "deno run --allow-write --allow-read --allow-env=XDG_DATA_HOME,HOME tools/build-schema.ts && deno fmt",
"build-versions": "deno run --allow-read --allow-write --allow-env tools/release.ts && deno fmt",
Expand All @@ -42,12 +38,13 @@
"@cross/env": "jsr:@cross/env@^1.0.2",
"@cross/fs": "jsr:@cross/fs@^0.1.11",
"@cross/jwt": "jsr:@cross/jwt@^0.4.7",
"@cross/kv": "jsr:@cross/kv@^0.0.13",
"@cross/runtime": "jsr:@cross/runtime@^1.0.0",
"@cross/service": "jsr:@cross/service@^1.0.3",
"@cross/test": "jsr:@cross/test@^0.0.9",
"@cross/utils": "jsr:@cross/utils@^0.12.0",
"@hexagon/croner": "jsr:@hexagon/croner@^8.0.2",
"@oak/oak": "jsr:@oak/oak@^15.0.0",
"@oak/oak": "jsr:@oak/oak@^16.0.0",
"@pup/api-client": "jsr:@pup/api-client@^1.0.6",
"@pup/api-definitions": "jsr:@pup/api-definitions@^1.0.2",
"@pup/common": "jsr:@pup/common@^1.0.3",
Expand Down
5 changes: 5 additions & 0 deletions docs/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ nav_order: 13

All notable changes to this project will be documented in this section.

## [1.0.0-rc.40] - Unreleased

- fix(core): Replace `Deno.Kv` with `@cross/kv` for cross-runtime compatibility, more compact logs and avoiding `--unstable`
- fix(core): Make Pup work in Node and Bun

## [1.0.0-rc.39] - 2024-05-04

- fix(core): Clustered processes were duplicated in API and `pup status`
Expand Down
3 changes: 1 addition & 2 deletions docs/src/contributing/packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ If you have experience with software packaging, your contribution can greatly en

- Pup can be compiled into an executable prior to packaging using `deno compile`. The procedure is described at
[https://deno.com/manual@v1.34.3/tools/compiler](https://deno.com/manual@v1.34.3/tools/compiler). The command should be similar to
`deno compile --allow-all --reload --unstable-kv --output pup pup.ts --external-installer`. The `--unstable-kv` flag should be included if the version you are packaging (mostly pre-releases)
requires unstable features according to `versions.json`.
`deno compile --allow-all --reload --output pup pup.ts --external-installer`.

- The `--external-installer` argument to the Pup script disables the built-in installer, hiding `setup` and `upgrade` options from `--help`.

Expand Down
1 change: 1 addition & 0 deletions docs/src/examples/telemetry/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@jsr:registry=https://npm.jsr.io
6 changes: 6 additions & 0 deletions docs/src/examples/telemetry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "module",
"dependencies": {
"@pup/telemetry": "npm:@jsr/pup__telemetry@^1.0.5"
}
}
21 changes: 12 additions & 9 deletions lib/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ async function main() {
if (baseArgument === "logs") {
const logStore = `${await toPersistentPath(configFile as string)}/.main.log`
const logger = new Logger(configuration!.logger || {}, logStore)
await logger.init()
const startTimestamp = checkedArgs.get("start") ? new Date(Date.parse(checkedArgs.get("start")!)).getTime() : undefined
const endTimestamp = checkedArgs.get("end") ? new Date(Date.parse(checkedArgs.get("end")!)).getTime() : undefined
const numberOfRows = checkedArgs.get("n") ? parseInt(checkedArgs.get("n")!, 10) : undefined
Expand Down Expand Up @@ -496,7 +497,7 @@ async function main() {
exit(1)
}
} catch (_e) {
console.error("Action failed: Could not contact the Pup instance.")
console.error("Action failed: Could not contact the Pup instance.", _e)
exit(1)
}
}
Expand Down Expand Up @@ -587,14 +588,16 @@ async function main() {
pup.init()

// Register for running pup.terminate() if not already run on clean exit
let hasRunShutdownCode = false
globalThis.addEventListener("beforeunload", (evt) => {
if (!hasRunShutdownCode) {
evt.preventDefault()
hasRunShutdownCode = true
;(async () => await pup.terminate(30000))()
}
})
if (globalThis.addEventListener) {
let hasRunShutdownCode = false
globalThis.addEventListener("beforeunload", (evt) => {
if (!hasRunShutdownCode) {
evt.preventDefault()
hasRunShutdownCode = true
;(async () => await pup.terminate(30000))()
}
})
}

if (CurrentRuntime === Runtime.Deno) {
// This is needed to trigger termination in Deno
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { filesize } from "filesize"
import { blockedFormatter, codeFormatter, naFormatter, restartsFormatter, statusFormatter } from "./formatters/strings.ts"
import { timeagoFormatter } from "./formatters/times.ts"
import { Configuration, DEFAULT_REST_API_HOSTNAME } from "../core/configuration.ts"
import { resolve } from "@std/path"
import { ApiApplicationState } from "@pup/api-definitions"
import { toResolvedAbsolutePath } from "@pup/common/path"

/**
* Helper which print the status of all running processes,
Expand All @@ -29,8 +29,8 @@ import { ApiApplicationState } from "@pup/api-definitions"
export function printStatus(configFile: string, configuration: Configuration, cwd: string | undefined, status: ApiApplicationState) {
// Print configuration
console.log("")
console.log(Colors.bold("Configuration:") + "\t" + resolve(configFile))
console.log(Colors.bold("Working dir:") + "\t" + cwd || "Not set (default: pup)")
console.log(Colors.bold("Configuration:") + "\t" + toResolvedAbsolutePath(configFile))
console.log(Colors.bold("Working dir:") + "\t" + (cwd ? toResolvedAbsolutePath(cwd as string) : "Not set (default: pup)"))
console.log(Colors.bold("Instance name:") + "\t" + (configuration.name || "Not set"))
console.log(Colors.bold("Rest API URL:") + "\thttp://" + (configuration.api?.hostname || DEFAULT_REST_API_HOSTNAME) + ":" + status.port)

Expand Down
3 changes: 0 additions & 3 deletions lib/cli/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ export async function upgrade(
if (ignoreCertificateErrorsString && ignoreCertificateErrorsString !== "") {
installCmd.push(ignoreCertificateErrorsString)
}
if (unstableInstall) {
installCmd.push("--unstable-kv")
}
installCmd.push("-n", "pup") // Installed command name = pup
installCmd.push(canaryInstall ? versions.canary_url : (requestedVersion as Version).url)

Expand Down
79 changes: 79 additions & 0 deletions lib/common/sysinfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { CurrentRuntime, Runtime } from "@cross/runtime"
import { ApiMemoryUsage, ApiSystemMemory } from "@pup/api-definitions"
import { freemem, loadavg, totalmem, uptime as nodeUptime } from "node:os"

export function memoryUsage(): ApiMemoryUsage {
let memoryUsageResult: ApiMemoryUsage
if (CurrentRuntime === Runtime.Deno) {
//@ts-ignore cross-runtime
const { external, heapTotal, heapUsed, rss } = Deno.memoryUsage()
memoryUsageResult = { external, heapTotal, heapUsed, rss }
} else if (
CurrentRuntime === Runtime.Node || CurrentRuntime === Runtime.Bun
) {
//@ts-ignore cross-runtime
const { external = 0, heapTotal, heapUsed, rss } = process.memoryUsage()
memoryUsageResult = { external, heapTotal, heapUsed, rss }
} else {
memoryUsageResult = { external: 0, heapTotal: 0, heapUsed: 0, rss: 0 }
}
return memoryUsageResult
}

export function loadAvg(): number[] {
let loadAvgResult: number[]
if (CurrentRuntime === Runtime.Deno) {
loadAvgResult = Deno.loadavg()
} else if (CurrentRuntime === Runtime.Node || CurrentRuntime === Runtime.Bun) {
// Node.js and Bun provide os module for loadAvg
loadAvgResult = loadavg()
} else {
// Unsupported runtime
loadAvgResult = []
}
return loadAvgResult
}

export function uptime(): number {
let uptimeResult: number
if (CurrentRuntime === Runtime.Deno) {
uptimeResult = Deno.osUptime()
} else if (CurrentRuntime === Runtime.Node || CurrentRuntime === Runtime.Bun) {
// Node.js and Bun provide os module for uptime
uptimeResult = nodeUptime()
} else {
uptimeResult = -1
}
return uptimeResult
}

export function systemMemoryInfo(): ApiSystemMemory {
let memoryInfoResult: ApiSystemMemory
if (CurrentRuntime === Runtime.Deno) {
memoryInfoResult = Deno.systemMemoryInfo()
} else if (CurrentRuntime === Runtime.Node || CurrentRuntime === Runtime.Bun) {
// Node.js and Bun don't have a direct equivalent to Deno.systemMemoryInfo
// We can try to approximate values using os module (limited information)
memoryInfoResult = {
total: totalmem(),
free: freemem(),
available: -1, // Not directly available
buffers: -1, // Not directly available
cached: -1, // Not directly available
swapTotal: -1, // Approximate swap total
swapFree: -1, // Not directly available
}
} else {
// Unsupported runtime
memoryInfoResult = {
total: -1,
free: -1,
available: -1,
buffers: -1,
cached: -1,
swapTotal: -1,
swapFree: -1,
}
}
return memoryInfoResult
}
2 changes: 1 addition & 1 deletion lib/core/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { PluginConfiguration } from "@pup/plugin"

// Logger constants
export const DEFAULT_INTERNAL_LOG_HOURS = 48
export const KV_SIZE_LIMIT_BYTES = 65_536
export const KV_LIMIT_STRING_LENGTH_BYTES = 12_000

// Core constants
export const MAINTENANCE_INTERVAL_MS = 900_000
Expand Down
9 changes: 8 additions & 1 deletion lib/core/loadbalancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @license MIT
*/

import { CurrentRuntime, Runtime } from "@cross/runtime"
import { LOAD_BALANCER_DEFAULT_VALIDATION_INTERVAL_S } from "./configuration.ts"

export enum BalancingStrategy {
Expand Down Expand Up @@ -77,7 +78,13 @@ export class LoadBalancer {
private setupValidationTimer(): number {
const timer = setInterval(() => this.validateBackends(), this.validationInterval * 1000)
// Make the timer non-blocking
Deno.unrefTimer(timer)
if (CurrentRuntime === Runtime.Deno) {
Deno.unrefTimer(timer)
// @ts-ignore unref exists in node and bun
} else if (timer.unref) {
// @ts-ignore unref exists in node and bun
timer.unref()
}
return timer
}

Expand Down
Loading

0 comments on commit 36b6c35

Please sign in to comment.