chore(lint): parallelize safe await-in-loop in server

This commit is contained in:
Mohamed Boudra
2026-04-24 01:33:07 +07:00
parent 16a48db75b
commit cb6987b0a2
11 changed files with 147 additions and 128 deletions

View File

@@ -163,16 +163,21 @@ export class AgentStorage {
this.beginDelete(agentId);
await (this.pendingWrites.get(agentId) ?? Promise.resolve());
const paths = Array.from(this.pathsById.get(agentId) ?? []);
for (const filePath of paths) {
try {
await fs.unlink(filePath);
} catch (error) {
const code = (error as NodeJS.ErrnoException).code;
if (code && code !== "ENOENT") {
this.logger.warn({ err: error, agentId, filePath }, "Failed to remove agent record file");
await Promise.all(
paths.map(async (filePath) => {
try {
await fs.unlink(filePath);
} catch (error) {
const code = (error as NodeJS.ErrnoException).code;
if (code && code !== "ENOENT") {
this.logger.warn(
{ err: error, agentId, filePath },
"Failed to remove agent record file",
);
}
}
}
}
}),
);
this.cache.delete(agentId);
this.pathById.delete(agentId);

View File

@@ -858,11 +858,13 @@ export async function createPaseoDaemon(
async function closeAllAgents(logger: Logger, agentManager: AgentManager): Promise<void> {
const agents = agentManager.listAgents();
for (const agent of agents) {
try {
await agentManager.closeAgent(agent.id);
} catch (err) {
logger.error({ err, agentId: agent.id }, "Failed to close agent");
}
}
await Promise.all(
agents.map(async (agent) => {
try {
await agentManager.closeAgent(agent.id);
} catch (err) {
logger.error({ err, agentId: agent.id }, "Failed to close agent");
}
}),
);
}

View File

@@ -72,15 +72,16 @@ export async function listAvailableEditorTargets(
const platform = dependencies.platform ?? process.platform;
const findExecutableFn = dependencies.findExecutable ?? findExecutable;
const supportedTargets = EDITOR_TARGETS.filter((target) =>
isTargetSupportedOnPlatform(target, platform),
);
const executables = await Promise.all(
supportedTargets.map((target) => findExecutableFn(target.command)),
);
const results: EditorTargetDescriptorPayload[] = [];
for (const target of EDITOR_TARGETS) {
if (!isTargetSupportedOnPlatform(target, platform)) {
continue;
}
const executable = await findExecutableFn(target.command);
if (!executable) {
continue;
}
for (let i = 0; i < supportedTargets.length; i += 1) {
if (!executables[i]) continue;
const target = supportedTargets[i]!;
results.push({
id: target.id,
label: target.label,

View File

@@ -143,16 +143,18 @@ export async function archivePaseoWorktree(
dependencies.github.invalidate({ cwd });
}
for (const workspaceId of affectedWorkspaceIds) {
try {
await dependencies.archiveWorkspaceRecord(workspaceId);
} catch (error) {
dependencies.sessionLogger?.warn(
{ err: error, workspaceId },
"Failed to archive workspace record; worktree FS already removed",
);
}
}
await Promise.all(
Array.from(affectedWorkspaceIds).map(async (workspaceId) => {
try {
await dependencies.archiveWorkspaceRecord(workspaceId);
} catch (error) {
dependencies.sessionLogger?.warn(
{ err: error, workspaceId },
"Failed to archive workspace record; worktree FS already removed",
);
}
}),
);
for (const agentId of removedAgents) {
dependencies.emit({
@@ -179,21 +181,25 @@ export async function killTerminalsUnderPath(
}
const terminalIds: string[] = [];
const terminalDirectories = [...terminalManager.listDirectories()];
for (const terminalCwd of terminalDirectories) {
if (!dependencies.isPathWithinRoot(rootPath, terminalCwd)) {
continue;
}
try {
const terminals = await terminalManager.getTerminals(terminalCwd);
for (const terminal of terminals) {
terminalIds.push(terminal.id);
const relevantCwds = [...terminalManager.listDirectories()].filter((terminalCwd) =>
dependencies.isPathWithinRoot(rootPath, terminalCwd),
);
const terminalLists = await Promise.all(
relevantCwds.map(async (terminalCwd) => {
try {
return await terminalManager.getTerminals(terminalCwd);
} catch (error) {
dependencies.sessionLogger.warn(
{ err: error, cwd: terminalCwd },
"Failed to enumerate worktree terminals during archive",
);
return [];
}
} catch (error) {
dependencies.sessionLogger.warn(
{ err: error, cwd: terminalCwd },
"Failed to enumerate worktree terminals during archive",
);
}),
);
for (const terminals of terminalLists) {
for (const terminal of terminals) {
terminalIds.push(terminal.id);
}
}

View File

@@ -57,9 +57,7 @@ export class PushService {
batches.push(messages.slice(i, i + MAX_BATCH_SIZE));
}
for (const batch of batches) {
await this.sendBatch(batch);
}
await Promise.all(batches.map((batch) => this.sendBatch(batch)));
}
private async sendBatch(messages: ExpoPushMessage[]): Promise<void> {

View File

@@ -98,13 +98,15 @@ export class ScriptHealthMonitor {
const changedWorkspaceIds = new Set<string>();
const now = Date.now();
for (const route of routes) {
const state = this.getOrCreateState(route, now);
if (now - state.registeredAt < this.graceMs) {
continue;
}
const isHealthy = await this.probeRoute(route.port);
const probeTargets = routes
.map((route) => ({ route, state: this.getOrCreateState(route, now) }))
.filter(({ state }) => now - state.registeredAt >= this.graceMs);
const healthResults = await Promise.all(
probeTargets.map(({ route }) => this.probeRoute(route.port)),
);
for (let i = 0; i < probeTargets.length; i += 1) {
const { route, state } = probeTargets[i]!;
const isHealthy = healthResults[i]!;
const previousHealth = state.health;
if (isHealthy) {

View File

@@ -150,13 +150,18 @@ export class WorkspaceReconciliationService {
}
// 3. Reconcile git metadata for active projects whose directories still exist
for (const project of activeProjects) {
if (project.archivedAt) continue;
const projectsToReconcile = activeProjects.filter((project) => {
if (project.archivedAt) return false;
const siblings = workspacesByProject.get(project.projectId) ?? [];
if (siblings.length === 0) continue;
if (!existsSync(project.rootPath)) continue;
await this.reconcileProject(project, siblings, changes);
}
if (siblings.length === 0) return false;
if (!existsSync(project.rootPath)) return false;
return true;
});
await Promise.all(
projectsToReconcile.map((project) =>
this.reconcileProject(project, workspacesByProject.get(project.projectId) ?? [], changes),
),
);
if (changes.length > 0 && this.onChanges) {
this.onChanges(changes);
@@ -208,27 +213,28 @@ export class WorkspaceReconciliationService {
});
}
for (const workspace of siblings) {
if (!existsSync(workspace.cwd)) continue;
const existingSiblings = siblings.filter((workspace) => existsSync(workspace.cwd));
await Promise.all(
existingSiblings.map(async (workspace) => {
const wsDirName = workspace.cwd.split(/[\\/]/).filter(Boolean).at(-1) ?? workspace.cwd;
const wsGit = await this.readWorkspaceGitMetadata(workspace.cwd, wsDirName);
const wsDirName = workspace.cwd.split(/[\\/]/).filter(Boolean).at(-1) ?? workspace.cwd;
const wsGit = await this.readWorkspaceGitMetadata(workspace.cwd, wsDirName);
if (wsGit.projectKind === "git" && workspace.displayName !== wsGit.workspaceDisplayName) {
const timestamp = new Date().toISOString();
await this.workspaceRegistry.upsert({
...workspace,
displayName: wsGit.workspaceDisplayName,
updatedAt: timestamp,
});
changes.push({
kind: "workspace_updated",
workspaceId: workspace.workspaceId,
directory: workspace.cwd,
fields: { displayName: wsGit.workspaceDisplayName },
});
}
}
if (wsGit.projectKind === "git" && workspace.displayName !== wsGit.workspaceDisplayName) {
const timestamp = new Date().toISOString();
await this.workspaceRegistry.upsert({
...workspace,
displayName: wsGit.workspaceDisplayName,
updatedAt: timestamp,
});
changes.push({
kind: "workspace_updated",
workspaceId: workspace.workspaceId,
directory: workspace.cwd,
fields: { displayName: wsGit.workspaceDisplayName },
});
}
}),
);
}
private async readWorkspaceGitMetadata(cwd: string, directoryName: string) {

View File

@@ -77,13 +77,18 @@ export async function bootstrapWorkspaceRegistries(options: {
records: StoredAgentRecord[];
}
>();
for (const record of activeRecords) {
const normalizedCwd = normalizeWorkspaceId(record.cwd);
const placement = await buildProjectPlacementForCwd({
cwd: normalizedCwd,
workspaceGitService: options.workspaceGitService,
});
const workspaceId = deriveWorkspaceId(normalizedCwd, placement.checkout);
const placements = await Promise.all(
activeRecords.map(async (record) => {
const normalizedCwd = normalizeWorkspaceId(record.cwd);
const placement = await buildProjectPlacementForCwd({
cwd: normalizedCwd,
workspaceGitService: options.workspaceGitService,
});
const workspaceId = deriveWorkspaceId(normalizedCwd, placement.checkout);
return { record, placement, workspaceId };
}),
);
for (const { record, placement, workspaceId } of placements) {
const existing = recordsByWorkspaceId.get(workspaceId) ?? { placement, records: [] };
existing.records.push(record);
recordsByWorkspaceId.set(workspaceId, existing);

View File

@@ -188,9 +188,14 @@ export async function detectStaleWorkspaces(
): Promise<Set<string>> {
const staleWorkspaceIds = new Set<string>();
for (const workspace of input.activeWorkspaces) {
const dirExists = await input.checkDirectoryExists(workspace.cwd);
if (!dirExists) {
const existenceChecks = await Promise.all(
input.activeWorkspaces.map(async (workspace) => ({
workspace,
exists: await input.checkDirectoryExists(workspace.cwd),
})),
);
for (const { workspace, exists } of existenceChecks) {
if (!exists) {
staleWorkspaceIds.add(workspace.workspaceId);
}
}

View File

@@ -181,16 +181,9 @@ export class FileTaskStore implements TaskStore {
await this.ensureDir();
try {
const files = await readdir(this.dir);
const tasks: Task[] = [];
for (const file of files) {
if (file.endsWith(".md")) {
const id = file.slice(0, -3);
const task = await this.readTask(id);
if (task) {
tasks.push(task);
}
}
}
const ids = files.filter((file) => file.endsWith(".md")).map((file) => file.slice(0, -3));
const loaded = await Promise.all(ids.map((id) => this.readTask(id)));
const tasks: Task[] = loaded.filter((task): task is Task => task !== null);
// Sort by created date (oldest first) for consistent ordering
return tasks.sort((a, b) => a.created.localeCompare(b.created));
} catch (error) {

View File

@@ -764,30 +764,26 @@ async function listWorkspaceChildEntries(input: {
const dirents = await readdir(input.directory, { withFileTypes: true }).catch(
() => [] as Dirent[],
);
const entries: ChildWorkspaceEntry[] = [];
for (const dirent of dirents) {
if (isHiddenDirectoryName(dirent.name)) {
continue;
}
if (isIgnoredWorkspaceDirectoryName(dirent.name)) {
continue;
}
const candidatePath = path.join(input.directory, dirent.name);
const entry = await resolveWorkspaceCandidate({
candidatePath,
dirent,
workspaceRoot: input.workspaceRoot,
});
if (!entry) {
continue;
}
entries.push({
name: dirent.name,
absolutePath: entry.absolutePath,
kind: entry.kind,
});
}
const candidates = dirents.filter(
(dirent) =>
!isHiddenDirectoryName(dirent.name) && !isIgnoredWorkspaceDirectoryName(dirent.name),
);
const resolved = await Promise.all(
candidates.map(async (dirent) => {
const candidatePath = path.join(input.directory, dirent.name);
const entry = await resolveWorkspaceCandidate({
candidatePath,
dirent,
workspaceRoot: input.workspaceRoot,
});
return entry
? { name: dirent.name, absolutePath: entry.absolutePath, kind: entry.kind }
: null;
}),
);
const entries: ChildWorkspaceEntry[] = resolved.filter(
(entry): entry is ChildWorkspaceEntry => entry !== null,
);
setWorkspaceEntryListCache(input.directory, {
expiresAt: now + DIRECTORY_LIST_CACHE_TTL_MS,