Skip to content

Commit

Permalink
fix: race condition singleton records (#1495)
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra authored Jul 5, 2023
1 parent 38a0578 commit 6c2dda5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Cache } from '../Cache'

import { LRUMap } from 'lru_map'

import { AriesFrameworkError } from '../../../error'
import { AriesFrameworkError, RecordDuplicateError } from '../../../error'

import { SingleContextLruCacheRecord } from './SingleContextLruCacheRecord'
import { SingleContextLruCacheRepository } from './SingleContextLruCacheRepository'
Expand Down Expand Up @@ -114,7 +114,20 @@ export class SingleContextStorageLruCache implements Cache {
entries: new Map(),
})

await cacheRepository.save(agentContext, cacheRecord)
try {
await cacheRepository.save(agentContext, cacheRecord)
} catch (error) {
// This addresses some race conditions issues where we first check if the record exists
// then we create one if it doesn't, but another process has created one in the meantime
// Although not the most elegant solution, it addresses the issues
if (error instanceof RecordDuplicateError) {
// the record already exists, which is our intended end state
// we can ignore this error and fetch the existing record
return cacheRepository.getById(agentContext, CONTEXT_STORAGE_LRU_CACHE_ID)
} else {
throw error
}
}
}

return cacheRecord
Expand Down
40 changes: 27 additions & 13 deletions packages/core/src/modules/routing/services/MediatorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { ForwardMessage, MediationRequestMessage } from '../messages'
import { EventEmitter } from '../../../agent/EventEmitter'
import { InjectionSymbols } from '../../../constants'
import { KeyType } from '../../../crypto'
import { AriesFrameworkError } from '../../../error'
import { AriesFrameworkError, RecordDuplicateError } from '../../../error'
import { Logger } from '../../../logger'
import { injectable, inject } from '../../../plugins'
import { ConnectionService } from '../../connections'
Expand Down Expand Up @@ -38,7 +38,6 @@ export class MediatorService {
private mediatorRoutingRepository: MediatorRoutingRepository
private eventEmitter: EventEmitter
private connectionService: ConnectionService
private _mediatorRoutingRecord?: MediatorRoutingRecord

public constructor(
mediationRepository: MediationRepository,
Expand Down Expand Up @@ -209,18 +208,33 @@ export class MediatorService {
routingKeys: [routingKey.publicKeyBase58],
})

await this.mediatorRoutingRepository.save(agentContext, routingRecord)

this.eventEmitter.emit(agentContext, {
type: RoutingEventTypes.RoutingCreatedEvent,
payload: {
routing: {
endpoints: agentContext.config.endpoints,
routingKeys: [],
recipientKey: routingKey,
try {
await this.mediatorRoutingRepository.save(agentContext, routingRecord)
this.eventEmitter.emit(agentContext, {
type: RoutingEventTypes.RoutingCreatedEvent,
payload: {
routing: {
endpoints: agentContext.config.endpoints,
routingKeys: [],
recipientKey: routingKey,
},
},
},
})
})
} catch (error) {
// This addresses some race conditions issues where we first check if the record exists
// then we create one if it doesn't, but another process has created one in the meantime
// Although not the most elegant solution, it addresses the issues
if (error instanceof RecordDuplicateError) {
// the record already exists, which is our intended end state
// we can ignore this error and fetch the existing record
return this.mediatorRoutingRepository.getById(
agentContext,
this.mediatorRoutingRepository.MEDIATOR_ROUTING_RECORD_ID
)
} else {
throw error
}
}

return routingRecord
}
Expand Down

0 comments on commit 6c2dda5

Please sign in to comment.