mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Create VoidLocker to disable locking resources
* add: Add VoidLocker and unittest * Update src/util/locking/VoidLocker.ts Co-authored-by: Ruben Verborgh <ruben@verborgh.org> * Update src/util/locking/VoidLocker.ts Co-authored-by: Joachim Van Herwegen <joachimvh@gmail.com> * update: noop function and add debug void config * add: debug-void in readme * Update RELEASE_NOTES.md Co-authored-by: Joachim Van Herwegen <joachimvh@gmail.com> * Update config/util/README.md Co-authored-by: Joachim Van Herwegen <joachimvh@gmail.com> * add: missing line Co-authored-by: lina <lina7906@gmail.com> Co-authored-by: Ruben Verborgh <ruben@verborgh.org> Co-authored-by: Joachim Van Herwegen <joachimvh@gmail.com>
This commit is contained in:
parent
4241c5348d
commit
9a1f324685
@ -3,6 +3,7 @@
|
||||
## v3.0.0
|
||||
### New features
|
||||
- The Identity Provider now uses the `webid` scope as required for Solid-OIDC.
|
||||
- The `VoidLocker` can be used to disable locking for development/testing purposes. This can be enabled by changing the `/config/util/resource-locker/` import to `debug-void.json`
|
||||
|
||||
### Configuration changes
|
||||
You might need to make changes to your v2 configuration if you use a custom config.
|
||||
|
@ -36,6 +36,7 @@ to the ChainedConverter list.
|
||||
|
||||
## Resource-locker
|
||||
Which locking mechanism to use to for example prevent 2 write simultaneous write requests.
|
||||
* *debug-void*: No locking mechanism, does not prevent simultaneous read/writes.
|
||||
* *memory*: Uses an in-memory locking mechanism.
|
||||
* *redis*: Uses a Redis store for locking.
|
||||
|
||||
|
13
config/util/resource-locker/debug-void.json
Normal file
13
config/util/resource-locker/debug-void.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^2.0.0/components/context.jsonld",
|
||||
"@graph": [
|
||||
{
|
||||
"comment": [
|
||||
"DO NOT USE IN PRODUCTION. ONLY FOR DEVELOPMENT, TESTING, OR DEBUGGING.",
|
||||
"Allows multiple simultaneous read operations and write operations without locks."
|
||||
],
|
||||
"@id": "urn:solid-server:default:ResourceLocker",
|
||||
"@type": "VoidLocker"
|
||||
}
|
||||
]
|
||||
}
|
@ -363,6 +363,7 @@ export * from './util/locking/RedisResourceLocker';
|
||||
export * from './util/locking/ResourceLocker';
|
||||
export * from './util/locking/SingleThreadedResourceLocker';
|
||||
export * from './util/locking/WrappedExpiringReadWriteLocker';
|
||||
export * from './util/locking/VoidLocker';
|
||||
|
||||
// Util/Templates
|
||||
export * from './util/templates/ChainedTemplateEngine';
|
||||
|
34
src/util/locking/VoidLocker.ts
Normal file
34
src/util/locking/VoidLocker.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../../logging/LogUtil';
|
||||
import type { ExpiringReadWriteLocker } from './ExpiringReadWriteLocker';
|
||||
|
||||
/**
|
||||
* This locker will execute the whileLocked function without any locking mechanism
|
||||
*
|
||||
* Do not use this locker in combination with storages that doesn't handle concurrent read/writes gracefully
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
function noop(): void {}
|
||||
|
||||
export class VoidLocker implements ExpiringReadWriteLocker {
|
||||
protected readonly logger = getLoggerFor(this);
|
||||
|
||||
public constructor() {
|
||||
this.logger.warn('Locking mechanism disabled; data integrity during parallel requests not guaranteed.');
|
||||
}
|
||||
|
||||
public async withReadLock<T>(
|
||||
identifier: ResourceIdentifier,
|
||||
whileLocked: (maintainLock: () => void) => T | Promise<T>,
|
||||
): Promise<T> {
|
||||
return whileLocked(noop);
|
||||
}
|
||||
|
||||
public async withWriteLock<T>(
|
||||
identifier: ResourceIdentifier,
|
||||
whileLocked: (maintainLock: () => void) => T | Promise<T>,
|
||||
): Promise<T> {
|
||||
return whileLocked(noop);
|
||||
}
|
||||
}
|
27
test/unit/util/locking/VoidLocker.test.ts
Normal file
27
test/unit/util/locking/VoidLocker.test.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import type { ResourceIdentifier } from '../../../../src';
|
||||
import { VoidLocker } from '../../../../src/util/locking/VoidLocker';
|
||||
|
||||
describe('A VoidLocker', (): void => {
|
||||
it('invokes the whileLocked function immediately with readLock.', async(): Promise<void> => {
|
||||
const locker = new VoidLocker();
|
||||
const identifier: ResourceIdentifier = { path: 'http://test.com/res' };
|
||||
const whileLocked = jest.fn().mockImplementation((maintainLockFn: () => void): void => {
|
||||
maintainLockFn();
|
||||
});
|
||||
|
||||
await locker.withReadLock(identifier, whileLocked);
|
||||
|
||||
expect(whileLocked).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('invokes the whileLocked function immediately with writeLock.', async(): Promise<void> => {
|
||||
const locker = new VoidLocker();
|
||||
const identifier: ResourceIdentifier = { path: 'http://test.com/res' };
|
||||
const whileLocked = jest.fn().mockImplementation((maintainLockFn: () => void): void => {
|
||||
maintainLockFn();
|
||||
});
|
||||
await locker.withWriteLock(identifier, whileLocked);
|
||||
|
||||
expect(whileLocked).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user