Skip to content

Commit

Permalink
chore(compas): minimize dangling promises
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkdev98 committed Sep 9, 2023
1 parent b0daa14 commit 1ec564e
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export class CacheCleanupIntegration extends BaseIntegration {
this.state.cache.cachesCleaned = true;

if (!hasPreviouslyCleaned) {
return await this.state.emitCacheUpdated();
await this.cleanup();
}
}

async onConfigUpdated() {
await super.onConfigUpdated();

await this.cleanup();
this.state.runTask("CachesCleanup", this.cleanup());
}

async cleanup() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export class FileWatcherIntegration extends BaseIntegration {
);
}

// Dangling promise!
boundEmitFileChange(events.map((it) => it.path));
},
FileWatcherIntegration.DEFAULT_WATCH_OPTIONS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export class InferredActionsIntegration extends BaseIntegration {
await super.init();

if (isNil(this.state.cache.availableActions)) {
await this.resolveAvailableActions();
this.state.runTask(
"inferredActionsResolve",
this.resolveAvailableActions(),
);
}

this.state.fileChangeRegister.push({
Expand All @@ -27,12 +30,18 @@ export class InferredActionsIntegration extends BaseIntegration {

async onCacheUpdated() {
await super.onCacheUpdated();
await this.resolveAvailableActions();
this.state.runTask(
"inferredActionsResolve",
this.resolveAvailableActions(),
);
}

async onFileChanged(paths) {
await super.onFileChanged(paths);
await this.resolveAvailableActions();
this.state.runTask(
"inferredActionsResolve",
this.resolveAvailableActions(),
);
}

async resolveAvailableActions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ export class PackageManagerIntegration extends BaseIntegration {
if (!this.state.cache.packageManager) {
await this.resolve();

// TODO: do we want to start with an 'await this.execute();'
// May want to do that as background task.
this.state.runTask("packageManagerExecute", this.execute());
}

this.state.fileChangeRegister.push({
Expand Down Expand Up @@ -62,7 +61,7 @@ export class PackageManagerIntegration extends BaseIntegration {
}

if (installCommand) {
return this.execute();
this.state.runTask("packageManagerExecute", this.execute());
}
}

Expand Down
77 changes: 62 additions & 15 deletions packages/compas/src/main/development/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class State {
};
}

// ==== generic ====
// ==== generic lifecycle ====

async init() {
debugTimeStart(`State#init`);
Expand All @@ -108,11 +108,15 @@ export class State {
new ConfigLoaderIntegration(this),
new RootDirectoriesIntegration(this),
new CacheCleanupIntegration(this),
new InferredActionsIntegration(this),
new ActionsIntegration(this),

// Try to keep the above list minimal.

new PackageManagerIntegration(this),
new InferredActionsIntegration(this),

// Should be the last integration, since it will
// Should be the last integration, since it will process file changes since the
// last snapshot.
new FileWatcherIntegration(this),
];

Expand Down Expand Up @@ -208,6 +212,48 @@ export class State {
}
}

// ==== background tasks ====

/**
*
* @param {string} name
* @param {Promise|(() => Promise<any>)} task
* @param {{
* exitOnFailure?: boolean,
* }} [options]
* @returns {*}
*/
runTask(name, task, { exitOnFailure } = {}) {
if (typeof task === "function") {
return this.runTask(name, task, { exitOnFailure });
}

if (!(task instanceof Promise)) {
throw AppError.serverError({
message: "Received a task that isn't a promise.",
name,
task,
});
}

const _self = this;

debugPrint(`State#runTask :: ${name} :: registered`);

task
.then(() => {
debugPrint(`State#runTask :: ${name} :: fulfilled`);
})
.catch((e) => {
debugPrint(`State#runTask :: ${name} :: rejected`);
debugPrint(AppError.format(e));

if (exitOnFailure) {
_self.runTask("State#exit", _self.exit());
}
});
}

// ==== integrations ====

/**
Expand Down Expand Up @@ -249,7 +295,8 @@ export class State {
return;
}

// Rename a few keypress for easier matching and shorter shortcuts, we may want to expand this setup later.
// Rename a few keypress for easier matching and shorter shortcuts, we may want to
// expand this setup later.
if (key.name === "escape") {
key.name = "esc";
}
Expand All @@ -271,21 +318,21 @@ export class State {
emitFileChange(paths) {
debugPrint(`State#emitFileChange :: ${JSON.stringify(paths)}}`);

for (const integration of this.fileChangeRegister) {
if (micromatch.some(paths, integration.glob)) {
for (const registerItem of this.fileChangeRegister) {
if (micromatch.some(paths, registerItem.glob)) {
debugPrint(
`State#emitFileChange :: Matched ${integration.glob} for ${integration.integration.name} debouncing with ${integration.debounceDelay}.`,
`State#emitFileChange :: Matched ${registerItem.glob} for ${registerItem.integration.name} debouncing with ${registerItem.debounceDelay}.`,
);

if (integration.existingTimeout) {
integration.existingTimeout.refresh();
if (registerItem.existingTimeout) {
registerItem.existingTimeout.refresh();
} else {
integration.existingTimeout = setTimeout(() => {
// We don't ever clear the timeout, since refreshing will restart the timeout.

// Dangling promise!
integration.integration.onFileChanged(paths);
}, integration.debounceDelay);
registerItem.existingTimeout = setTimeout(() => {
registerItem.integration.state.runTask(
"Integration#onFileChaged",
registerItem.integration.onFileChanged(paths),
);
}, registerItem.debounceDelay);
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions packages/compas/src/main/development/tui.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export function tuiInit(state) {

// Exit listeners
process.on("SIGABRT", () => {
state.exit();
state.runTask("SIGABRT", state.exit(), { exitOnFailure: true });
});
process.on("SIGINT", () => {
state.exit();
state.runTask("SIGINT", state.exit(), { exitOnFailure: true });
});
process.on("beforeExit", () => {
state.exit();
state.runTask("beforeExit", state.exit());
});

process.stdout.on("resize", () => state.resizeScreen());
Expand All @@ -33,11 +33,12 @@ export function tuiInit(state) {
process.stdin.on("keypress", (char, raw) => {
if (raw.name === "c" && raw.ctrl) {
// Ctrl + C
state.exit();
state.runTask("Ctrl + C", state.exit(), { exitOnFailure: true });

return;
}

state.emitKeypress(raw);
state.runTask("tuiEmitKeyPress", state.emitKeypress(raw));
});
}

Expand Down

0 comments on commit 1ec564e

Please sign in to comment.