opencode-supertask 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,5 @@
1
+ declare function acquireLock(): boolean;
2
+ declare function releaseLock(): void;
1
3
  declare function main(): Promise<void>;
2
4
 
3
- export { main };
5
+ export { acquireLock, main, releaseLock };
@@ -6543,6 +6543,23 @@ var init_task_service = __esm({
6543
6543
  ).returning();
6544
6544
  return result.length;
6545
6545
  }
6546
+ static async resetOrphanRunningToPending() {
6547
+ const result = await db.update(tasks2).set({
6548
+ status: "pending",
6549
+ startedAt: null,
6550
+ finishedAt: null
6551
+ }).where(
6552
+ and(
6553
+ eq(tasks2.status, "running"),
6554
+ sql`NOT EXISTS (
6555
+ SELECT 1 FROM ${taskRuns2}
6556
+ WHERE ${taskRuns2.taskId} = ${tasks2.id}
6557
+ AND ${taskRuns2.status} = 'running'
6558
+ )`
6559
+ )
6560
+ ).returning();
6561
+ return result.length;
6562
+ }
6546
6563
  static async cancel(id, scope = {}) {
6547
6564
  const conditions = [
6548
6565
  eq(tasks2.id, id),
@@ -19176,6 +19193,15 @@ import { basename } from "path";
19176
19193
  function isSafePid(pid) {
19177
19194
  return Number.isInteger(pid) && pid > 1 && pid !== process.pid;
19178
19195
  }
19196
+ function isProcessAlive(pid) {
19197
+ if (!Number.isInteger(pid) || pid <= 0) return false;
19198
+ try {
19199
+ process.kill(pid, 0);
19200
+ return true;
19201
+ } catch (error) {
19202
+ return error instanceof Error && "code" in error && error.code === "EPERM";
19203
+ }
19204
+ }
19179
19205
  function inspectUnixProcess(pid) {
19180
19206
  const result = spawnSync("ps", ["-o", "pgid=", "-o", "command=", "-p", String(pid)], {
19181
19207
  encoding: "utf8",
@@ -19841,7 +19867,8 @@ function acquireLock() {
19841
19867
  sqlite.exec("BEGIN IMMEDIATE");
19842
19868
  const existing = sqlite.prepare("SELECT id, pid, heartbeat_at FROM gateway_lock WHERE id = 1").get();
19843
19869
  if (existing) {
19844
- if (now - existing.heartbeat_at < STALE_THRESHOLD_MS) {
19870
+ const lockHolderAlive = existing.pid !== pid && isProcessAlive(existing.pid);
19871
+ if (now - existing.heartbeat_at < STALE_THRESHOLD_MS && lockHolderAlive) {
19845
19872
  sqlite.exec("ROLLBACK");
19846
19873
  console.error(JSON.stringify({
19847
19874
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -19911,6 +19938,15 @@ async function main() {
19911
19938
  const worker = new WorkerEngine(cfg);
19912
19939
  const watchdog = new Watchdog(cfg);
19913
19940
  const scheduler = new Scheduler(cfg);
19941
+ const recoveredOrphans = await TaskService.resetOrphanRunningToPending();
19942
+ if (recoveredOrphans > 0) {
19943
+ console.log(JSON.stringify({
19944
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
19945
+ level: "warn",
19946
+ msg: "reset orphan running tasks to pending",
19947
+ count: recoveredOrphans
19948
+ }));
19949
+ }
19914
19950
  initializeGatewayHealth({
19915
19951
  workerPollIntervalMs: cfg.worker.pollIntervalMs,
19916
19952
  schedulerEnabled: cfg.scheduler.enabled,
@@ -19981,6 +20017,8 @@ if (import.meta.main) {
19981
20017
  main();
19982
20018
  }
19983
20019
  export {
19984
- main
20020
+ acquireLock,
20021
+ main,
20022
+ releaseLock
19985
20023
  };
19986
20024
  //# sourceMappingURL=index.js.map