@narumitw/pi-sync 0.49.9 → 0.49.10
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.
- package/package.json +1 -1
- package/src/state-directory.ts +55 -1
package/package.json
CHANGED
package/src/state-directory.ts
CHANGED
|
@@ -22,6 +22,14 @@ interface StateDirectoryGuard {
|
|
|
22
22
|
throwIfCompromised: () => void;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
interface SharedStateDirectoryGuard {
|
|
26
|
+
guard: Promise<StateDirectoryGuard>;
|
|
27
|
+
users: number;
|
|
28
|
+
closing?: Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const sharedStateDirectoryGuards = new Map<string, SharedStateDirectoryGuard>();
|
|
32
|
+
|
|
25
33
|
export function stateDir() {
|
|
26
34
|
const roots = inspectStateRoots();
|
|
27
35
|
if (roots.canonical) return canonicalStateDir();
|
|
@@ -40,7 +48,9 @@ export function stateDirectoryMigrationNotice() {
|
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
export async function withStateDirectoryAccess<T>(fn: () => Promise<T>): Promise<T> {
|
|
43
|
-
|
|
51
|
+
const roots = inspectStateRoots();
|
|
52
|
+
if (!roots.legacy) return fn();
|
|
53
|
+
return runWithStateDirectoryGuard(await acquireSharedStateDirectoryGuard(), fn);
|
|
44
54
|
}
|
|
45
55
|
|
|
46
56
|
export async function migrateLegacyStateDirectory(): Promise<StateDirectoryPreparation> {
|
|
@@ -87,6 +97,50 @@ export async function migrateLegacyStateDirectory(): Promise<StateDirectoryPrepa
|
|
|
87
97
|
});
|
|
88
98
|
}
|
|
89
99
|
|
|
100
|
+
async function acquireSharedStateDirectoryGuard(): Promise<StateDirectoryGuard> {
|
|
101
|
+
const key = migrationLockPath();
|
|
102
|
+
for (;;) {
|
|
103
|
+
let shared = sharedStateDirectoryGuards.get(key);
|
|
104
|
+
if (shared?.closing) {
|
|
105
|
+
await shared.closing;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (!shared) {
|
|
109
|
+
shared = { guard: acquireStateDirectoryGuard(), users: 0 };
|
|
110
|
+
sharedStateDirectoryGuards.set(key, shared);
|
|
111
|
+
}
|
|
112
|
+
shared.users += 1;
|
|
113
|
+
let guard: StateDirectoryGuard;
|
|
114
|
+
try {
|
|
115
|
+
guard = await shared.guard;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (sharedStateDirectoryGuards.get(key) === shared) {
|
|
118
|
+
sharedStateDirectoryGuards.delete(key);
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
let released = false;
|
|
123
|
+
return {
|
|
124
|
+
throwIfCompromised: guard.throwIfCompromised,
|
|
125
|
+
release: async () => {
|
|
126
|
+
if (released) return;
|
|
127
|
+
released = true;
|
|
128
|
+
shared.users -= 1;
|
|
129
|
+
if (shared.users > 0) return;
|
|
130
|
+
const closing = guard.release();
|
|
131
|
+
shared.closing = closing;
|
|
132
|
+
try {
|
|
133
|
+
await closing;
|
|
134
|
+
} finally {
|
|
135
|
+
if (sharedStateDirectoryGuards.get(key) === shared) {
|
|
136
|
+
sharedStateDirectoryGuards.delete(key);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
90
144
|
async function acquireStateDirectoryGuard(): Promise<StateDirectoryGuard> {
|
|
91
145
|
let compromisedError: Error | undefined;
|
|
92
146
|
const release = await lockfile.lock(getAgentDir(), {
|