Skip to content

Commit

Permalink
Find default config files in working directory when using --cwd. More…
Browse files Browse the repository at this point in the history
… graceful shutdown.
  • Loading branch information
Hexagon committed May 16, 2023
1 parent 04857a2 commit 0d54f91
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 29 deletions.
2 changes: 1 addition & 1 deletion application.meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

const Application = {
name: "pup",
version: "1.0.0-beta.24",
version: "1.0.0-beta.25",
repository: "https://github.com/hexagon/pup",
}

Expand Down
8 changes: 7 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ title: "11. Changelog"

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

## [1.0.0-beta.24] - 2023-05-16
## [1.0.0-beta.25] - 2023-05-16

- Fix: Find default config files in working directory when using `--cwd` without specifying `--config`
- Fix: Make --terminate even more graceful

## [1.0.0-beta.24] - 2023-05-15

- Documentation fixes
- Improve IPC implementation (speed and security)
- Improve cleanup functions and graceful shutdown
- Show outcome when running cli commands `start`, `stop`, `block`, `...`
- Fix: `pup terminate` should not require specifying an process id

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/telemetry/task-with-telemetry-1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const telemetry = new PupTelemetry(1)

// The task
let i = 0
console.log("Task running running")
console.log("Task running")

// Send data every 5th second
setInterval(() => {
Expand Down
26 changes: 20 additions & 6 deletions lib/cli/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { Configuration, generateConfiguration, ProcessConfiguration } from "../core/configuration.ts"
import { Args, jsonc } from "../../deps.ts"
import { Args, join, jsonc, resolve } from "../../deps.ts"
import { fileExists } from "../common/utils.ts"

/**
Expand Down Expand Up @@ -138,16 +138,30 @@ export async function removeFromConfigurationFile(configFile: string, checkedArg
*
* @async
*/
export async function findConfigFile(useConfigFile?: boolean, argumentsConfigFile?: string): Promise<string | undefined> {
export async function findConfigFile(useConfigFile?: boolean, argumentsConfigFile?: string, cwd?: string): Promise<string | undefined> {
// If not using config file, return undefined
if (!useConfigFile) return undefined

// If config file was specified in arguments, return it or throw if it does not exist
if (argumentsConfigFile) {
return argumentsConfigFile
const resolvedPath = resolve(argumentsConfigFile)
if (await fileExists(resolvedPath)) {
return resolvedPath
} else {
throw new Error("Specified configuration file does not exist.")
}
}

if (await fileExists("./pup.jsonc")) {
return "./pup.jsonc"
// Try to find configuration file, jsonc first. Take cwd into account.
let jsonPath = "./pup.json"
let jsoncPath = "./pup.jsonc"
if (cwd) {
jsonPath = join(resolve(cwd), jsonPath)
jsoncPath = join(resolve(cwd), jsoncPath)
}
if (await fileExists(jsoncPath)) {
return jsoncPath
} else {
return "./pup.json"
return jsonPath
}
}
2 changes: 1 addition & 1 deletion lib/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async function main(inputArgs: string[]) {
const useConfigFile = !runWithoutConfig
let configFile
if (useConfigFile) {
configFile = await findConfigFile(useConfigFile, checkedArgs.config)
configFile = await findConfigFile(useConfigFile, checkedArgs.config, checkedArgs.cwd)
}

/**
Expand Down
16 changes: 9 additions & 7 deletions lib/common/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class FileIPC {
private watcher?: Deno.FsWatcher

constructor(filePath: string, staleMessageLimitMs?: number, debounceTimeMs?: number) {
this.filePath = filePath
this.filePath = resolve(filePath)
this.dirPath = resolve(dirname(filePath)) // Get directory of the file
this.fileName = basename(filePath) // Get name of the file
this.staleMessageLimitMs = staleMessageLimitMs ?? 30000
Expand All @@ -43,7 +43,7 @@ export class FileIPC {
* get called more than once in a short amount of time (as specified by debounceTimeMs). The received messages
* from the extractMessages call are then added to the messageQueue to be consumed by the receiveData generator.
*/
public async startWatching() {
private async startWatching() {
// Create directory if it doesn't exist
await Deno.mkdir(this.dirPath, { recursive: true })

Expand Down Expand Up @@ -191,7 +191,7 @@ export class FileIPC {
/**
* Close the file-based IPC and remove the IPC file.
*/
async close(): Promise<void> {
async close(leaveFile?: boolean): Promise<void> {
// Flag as aborted
this.aborted = true

Expand All @@ -200,10 +200,12 @@ export class FileIPC {
this.watcher.close()
}
// Try to remove file, ignore failure
try {
await Deno.remove(this.filePath)
} catch (_e) {
// Ignore
if (!leaveFile) {
try {
await Deno.remove(this.filePath)
} catch (_e) {
// Ignore
}
}
}
}
7 changes: 4 additions & 3 deletions lib/core/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ class Logger {

// Write to temporary log file
if (this.tempLogPath) {
this.writeFile(this.tempLogPath, decorateGlobalFiles ? decoratedLogText : text)
// Ignore errors when writing to temp log file, as logs can occurr after the destination directory has been deleted
this.writeFile(this.tempLogPath, decorateGlobalFiles ? decoratedLogText : text, true)
}

// Write process log file(s)
Expand All @@ -121,13 +122,13 @@ class Logger {
}
}

private async writeFile(fileName: string, text: string) {
private async writeFile(fileName: string, text: string, quiet = false) {
// Strip colors
text = stripColor(text)
try {
await Deno.writeTextFile(fileName, `${text}\n`, { append: true })
} catch (_e) {
console.error(`Failed to write log '${fileName}'. The following message were not logged: ${text}.`)
if (!quiet) console.error(`Failed to write log '${fileName}'. The following message were not logged: ${text}.`)
}
}

Expand Down
16 changes: 8 additions & 8 deletions lib/core/pup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Pup {
private requestTerminate = false

private WATCHDOG_INTERVAL_MS = 2000
private watchdogTimer?: number

public temporaryStoragePath?: string
public persistentStoragePath?: string
Expand Down Expand Up @@ -256,7 +257,7 @@ class Pup {
// Reschedule watchdog
// ToDo: Exit if all processes are exhausted?
if (!this.requestTerminate) {
setTimeout(() => {
this.watchdogTimer = setTimeout(() => {
// Exit watchdog if terminating
this.watchdog()
}, this.WATCHDOG_INTERVAL_MS)
Expand All @@ -266,8 +267,6 @@ class Pup {
private async receiveData() {
if (this.ipc) {
try {
await this.ipc.startWatching()

for await (const messages of this.ipc.receiveData()) {
if (messages.length > 0) {
for (const message of messages) {
Expand Down Expand Up @@ -461,7 +460,8 @@ class Pup {
}
response = { success, action: "telemetry" }
} else if (parsedMessage.terminate) {
this.terminate(30000)
// Defer actual termination to allow response to be sent
setTimeout(() => this.terminate(30000), 500)
response = { success: true, action: "terminate" }
} else {
response = { success: false, action: "unknown" }
Expand All @@ -476,7 +476,9 @@ class Pup {
}

public async terminate(forceQuitMs: number) {
// Stop watchdog
this.requestTerminate = true
clearTimeout(this.watchdogTimer)

this.logger.log("terminate", "Termination requested")

Expand All @@ -493,17 +495,15 @@ class Pup {
this.logger.warn("terminate", "Terminating by force")
Deno.exit(0)
}, forceQuitMs)

// Unref force quit timer to allow the process to exit earlier
Deno.unrefTimer(timer)
Deno.unrefTimer(timer) // Unref force quit timer to allow the process to exit earlier

// Close IPC
if (this.ipc) {
await this.ipc.close()
}

// Cleanup
this.cleanup()
// this.cleanup()
}
}

Expand Down
2 changes: 1 addition & 1 deletion telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class PupTelemetry {
await ipc.sendData(JSON.stringify(message))

// Close the temporary IPC
ipc.close()
ipc.close(true)
} else {
// Ignore, process not run by Pup?
}
Expand Down

0 comments on commit 0d54f91

Please sign in to comment.