mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-19 07:17:00 +08:00
fix(server): handle expired lock re-release & external locker injection (#6145)
This commit is contained in:
@@ -6,7 +6,7 @@ import { MutexService } from './mutex';
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [MutexService, Locker],
|
||||
exports: [MutexService, Locker],
|
||||
exports: [MutexService],
|
||||
})
|
||||
export class MutexModule {}
|
||||
|
||||
|
||||
@@ -14,11 +14,21 @@ export const MUTEX_WAIT = 100;
|
||||
@Injectable({ scope: Scope.REQUEST })
|
||||
export class MutexService {
|
||||
protected logger = new Logger(MutexService.name);
|
||||
private readonly locker: Locker;
|
||||
|
||||
constructor(
|
||||
@Inject(CONTEXT) private readonly context: GraphqlContext,
|
||||
private readonly ref: ModuleRef
|
||||
) {}
|
||||
) {
|
||||
// nestjs will always find and injecting the locker from local module
|
||||
// so the RedisLocker implemented by the plugin mechanism will not be able to overwrite the internal locker
|
||||
// we need to use find and get the locker from the `ModuleRef` manually
|
||||
//
|
||||
// NOTE: when a `constructor` execute in normal service, the Locker module we expect may not have been initialized
|
||||
// but in the Service with `Scope.REQUEST`, we will create a separate Service instance for each request
|
||||
// at this time, all modules have been initialized, so we able to get the correct Locker instance in `constructor`
|
||||
this.locker = this.ref.get(Locker, { strict: false });
|
||||
}
|
||||
|
||||
protected getId() {
|
||||
let id = this.context.req.headers['x-transaction-id'] as string;
|
||||
@@ -55,10 +65,7 @@ export class MutexService {
|
||||
async lock(key: string) {
|
||||
try {
|
||||
return await retryable(
|
||||
() => {
|
||||
const locker = this.ref.get(Locker, { strict: false });
|
||||
return locker.lock(this.getId(), key);
|
||||
},
|
||||
() => this.locker.lock(this.getId(), key),
|
||||
MUTEX_RETRY,
|
||||
MUTEX_WAIT
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user