Skip to content

Commit 511a742

Browse files
committed
WIP
1 parent 486bc41 commit 511a742

File tree

2 files changed

+35
-93
lines changed

2 files changed

+35
-93
lines changed

src/LockBox.ts

Lines changed: 33 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { ErrorAsyncLocksLockBoxConflict } from './errors';
55

66
class LockBox<L extends Lockable = Lockable> implements Lockable {
77
protected _locks: Map<string, L> = new Map();
8-
// protected lockReleasers: Map<string, ResourceRelease> = new Map();
98

109
public lock(...requests: Array<LockRequest<L>>): ResourceAcquire<LockBox<L>> {
1110
return async () => {
@@ -44,24 +43,11 @@ class LockBox<L extends Lockable = Lockable> implements Lockable {
4443
const lockAcquire = lock.lock(...lockingParams);
4544
const [lockRelease] = await lockAcquire();
4645
locks.push([key, lockRelease, lock]);
47-
48-
// This doesn't work if we use RWLockWriter
49-
// this is because the lockRelease can be multiple ones
50-
// for any given lock, you may have multiple readers
51-
// locking a single key, this ends up overwriting it...
52-
// this means it is not equivalent
53-
// and would have to be held by the user
54-
// but the user can't do this unless it has direct access
55-
// because otherwise it has overlapping locks
56-
57-
// this.lockReleasers.set(key, lockRelease);
58-
5946
}
6047
} catch (e) {
6148
// Release all intermediate locks in reverse order
6249
locks.reverse();
6350
for (const [key, lockRelease, lock] of locks) {
64-
// this.lockReleasers.delete(key);
6551
await lockRelease();
6652
// If it is still locked, then it is held by a different context
6753
// only delete if no contexts are locking the lock
@@ -79,14 +65,7 @@ class LockBox<L extends Lockable = Lockable> implements Lockable {
7965
// Release all locks in reverse order
8066
locks.reverse();
8167
for (const [key, lockRelease, lock] of locks) {
82-
83-
// // The lock may already been unlocked early
84-
// if (this.lockReleasers.has(key)) {
85-
// this.lockReleasers.delete(key);
86-
// }
87-
8868
await lockRelease();
89-
9069
// If it is still locked, then it is held by a different context
9170
// only delete if no contexts are locking the lock
9271
if (!lock.isLocked()) {
@@ -99,13 +78,18 @@ class LockBox<L extends Lockable = Lockable> implements Lockable {
9978
};
10079
}
10180

102-
public lockMulti(...requests: Array<LockRequest<L>>): Array<[ToString, ResourceAcquire<L>]> {
81+
public lockMulti(
82+
...requests: Array<LockRequest<L>>
83+
): Array<[ToString, ResourceAcquire<L>]> {
10384
// Convert to strings
10485
// This creates a copy of the requests
105-
let requests_: Array<[string, ToString, new () => L, ...Parameters<L['lock']>]> =
106-
requests.map(([key, ...rest]) =>
107-
typeof key === 'string' ? [key, key, ...rest] : [key.toString(), key, ...rest],
108-
);
86+
let requests_: Array<
87+
[string, ToString, new () => L, ...Parameters<L['lock']>]
88+
> = requests.map(([key, ...rest]) =>
89+
typeof key === 'string'
90+
? [key, key, ...rest]
91+
: [key.toString(), key, ...rest],
92+
);
10993
// Sort to ensure lock hierarchy
11094
requests_.sort(([key1], [key2]) => {
11195
// Deterministic string comparison according to 16-bit code units
@@ -158,31 +142,14 @@ class LockBox<L extends Lockable = Lockable> implements Lockable {
158142
this._locks.delete(key);
159143
}
160144
},
161-
lock
145+
lock,
162146
];
163-
}
147+
},
164148
]);
165149
}
166150
return lockAcquires;
167151
}
168152

169-
// /**
170-
// * Unlock a sequence of lock keys
171-
// * Unlocking will be done in the order of the keys
172-
// * This allows imperative early unlocking of keys
173-
// * Prefer to use the lock releaser returned by `this.lock`
174-
// */
175-
// public async unlock(...keys: Array<ToString>): Promise<void> {
176-
// for (const k of keys) {
177-
// const key = k.toString();
178-
// const lockRelease = this.lockReleasers.get(key);
179-
// if (lockRelease != null) {
180-
// this.lockReleasers.delete(key);
181-
// await lockRelease();
182-
// }
183-
// }
184-
// }
185-
186153
get locks(): ReadonlyMap<string, L> {
187154
return this._locks;
188155
}
@@ -246,14 +213,15 @@ class LockBox<L extends Lockable = Lockable> implements Lockable {
246213
): Promise<T> {
247214
const f = params.pop() as (multiLocks: Array<[ToString, L]>) => Promise<T>;
248215
const lockAcquires = this.lockMulti(...(params as Array<LockRequest<L>>));
249-
const lockAcquires_: Array<ResourceAcquire<[ToString, L]>> = lockAcquires.map(
250-
([key, lockAcquire]) => (...r) => lockAcquire(...r).then(
251-
([lockRelease, lock]) => [
252-
lockRelease,
253-
[key, lock]
254-
] as [ResourceRelease, [ToString, L]]
255-
)
256-
);
216+
const lockAcquires_: Array<ResourceAcquire<[ToString, L]>> =
217+
lockAcquires.map(
218+
([key, lockAcquire]) =>
219+
(...r) =>
220+
lockAcquire(...r).then(
221+
([lockRelease, lock]) =>
222+
[lockRelease, [key, lock]] as [ResourceRelease, [ToString, L]],
223+
),
224+
);
257225
return withF(lockAcquires_, f);
258226
}
259227

@@ -275,24 +243,26 @@ class LockBox<L extends Lockable = Lockable> implements Lockable {
275243
public withMultiG<T, TReturn, TNext>(
276244
...params: [
277245
...requests: Array<LockRequest<L>>,
278-
g: (multiLocks: Array<[ToString, L]>) => AsyncGenerator<T, TReturn, TNext>,
246+
g: (
247+
multiLocks: Array<[ToString, L]>,
248+
) => AsyncGenerator<T, TReturn, TNext>,
279249
]
280250
) {
281251
const g = params.pop() as (
282252
multiLocks: Array<[ToString, L]>,
283253
) => AsyncGenerator<T, TReturn, TNext>;
284254
const lockAcquires = this.lockMulti(...(params as Array<LockRequest<L>>));
285-
const lockAcquires_: Array<ResourceAcquire<[ToString, L]>> = lockAcquires.map(
286-
([key, lockAcquire]) => (...r) => lockAcquire(...r).then(
287-
([lockRelease, lock]) => [
288-
lockRelease,
289-
[key, lock]
290-
] as [ResourceRelease, [ToString, L]]
291-
)
292-
);
255+
const lockAcquires_: Array<ResourceAcquire<[ToString, L]>> =
256+
lockAcquires.map(
257+
([key, lockAcquire]) =>
258+
(...r) =>
259+
lockAcquire(...r).then(
260+
([lockRelease, lock]) =>
261+
[lockRelease, [key, lock]] as [ResourceRelease, [ToString, L]],
262+
),
263+
);
293264
return withG(lockAcquires_, g);
294265
}
295-
296266
}
297267

298268
export default LockBox;

tests/LockBox.test.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import type { ResourceRelease } from '@matrixai/resources';
12
import type { LockRequest } from '@/types';
2-
import { ResourceRelease, withF, withG } from '@matrixai/resources';
3+
import { withF, withG } from '@matrixai/resources';
34
import LockBox from '@/LockBox';
45
import Lock from '@/Lock';
56
import RWLockReader from '@/RWLockReader';
@@ -396,33 +397,4 @@ describe(LockBox.name, () => {
396397
expect(lockBox.isLocked('1')).toBe(false);
397398
expect(lockBox.isLocked('2')).toBe(false);
398399
});
399-
// test('fine grained unlocking', async () => {
400-
// const lockBox = new LockBox();
401-
// const lockAcquire = lockBox.lock(['1', Lock], ['2', Lock]);
402-
// const [lockRelease] = await lockAcquire();
403-
// await lockBox.unlock('1');
404-
// await lockBox.unlock('1');
405-
// expect(lockBox.isLocked('1')).toBe(false);
406-
// expect(lockBox.isLocked('2')).toBe(true);
407-
// await lockBox.withF(['1', Lock], async () => {
408-
// expect(lockBox.isLocked('1')).toBe(true);
409-
// expect(lockBox.isLocked('2')).toBe(true);
410-
// });
411-
// expect(lockBox.isLocked('1')).toBe(false);
412-
// expect(lockBox.isLocked('2')).toBe(true);
413-
// await lockRelease();
414-
// expect(lockBox.isLocked('1')).toBe(false);
415-
// expect(lockBox.isLocked('2')).toBe(false);
416-
// await lockBox.withF(['1', Lock], ['2', Lock], async (lockBox) => {
417-
// expect(lockBox.isLocked('1')).toBe(true);
418-
// expect(lockBox.isLocked('2')).toBe(true);
419-
// await lockBox.unlock('1', '2');
420-
// expect(lockBox.isLocked('1')).toBe(false);
421-
// expect(lockBox.isLocked('2')).toBe(false);
422-
// await lockBox.withF(['1', Lock], ['2', Lock], async () => {
423-
// expect(lockBox.isLocked('1')).toBe(true);
424-
// expect(lockBox.isLocked('2')).toBe(true);
425-
// });
426-
// });
427-
// });
428400
});

0 commit comments

Comments
 (0)