Skip to content

Commit

Permalink
fix: 🐛 sharelocks deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
ignazio-bovo committed Nov 30, 2023
1 parent 4c6e3af commit ed864f4
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions src/utils/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ export class RepositoryOverlay<E extends AnyEntity = AnyEntity> {
return cachedFound.entity
}

const stored = await this.repository.findBy(where as FindOptionsWhere<E>)
const stored = await this.repository.find({
where: where as FindOptionsWhere<E>,
lock: { mode: 'pessimistic_write' },
})
for (const storedEntity of stored) {
// See if we have a cached version of this entity. If yes - prioritize the cached one!
const cached = this.cached.get(storedEntity.id)
Expand Down Expand Up @@ -190,7 +193,10 @@ export class RepositoryOverlay<E extends AnyEntity = AnyEntity> {
return cached.entity
}

const stored = await this.repository.findOneBy({ id } as FindOptionsWhere<E>)
const stored = await this.repository.findOne({
where: { id } as FindOptionsWhere<E>,
lock: { mode: 'pessimistic_write' },
})

if (stored) {
// Update cache if entity found
Expand All @@ -215,10 +221,13 @@ export class RepositoryOverlay<E extends AnyEntity = AnyEntity> {
)
.flatMap((e) => (e.entity ? [e.entity] : []))
// Get all stored child entities where child.parent_id = parent.id and child.id is NOT IN(cachedIds)
const storedChildren = await this.repository.findBy({
id: Not(In(cachedIds)),
[relation]: id,
} as FindOptionsWhere<E>)
const storedChildren = await this.repository.find({
where: {
id: Not(In(cachedIds)),
[relation]: id,
} as FindOptionsWhere<E>,
lock: { mode: 'pessimistic_write' },
})
// Cache loaded entities
const storedChildrenCached = storedChildren.map((c) => this.cache(c))
// Return concatinated result
Expand Down Expand Up @@ -349,7 +358,7 @@ export class EntityManagerOverlay {
const em = await (store as unknown as { em: () => Promise<EntityManager> }).em()
// Add "admin" schema to search path in order to be able to access "hidden" entities
await em.query('SET search_path TO admin,public')
const nextEntityIds = await em.find(NextEntityId, {})
const nextEntityIds = await em.find(NextEntityId, { lock: { mode: 'pessimistic_write' } })
return new EntityManagerOverlay(em, nextEntityIds, afterDbUpdte)
}

Expand Down

0 comments on commit ed864f4

Please sign in to comment.