This repository has been archived by the owner on Aug 11, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: race condition in
getFormat
(#299)
There can be a race condition in ipld, if multiple requests to `getFormat` happen concurrently. While one of the requests `await`s `this.loadFormat`, another request might finish loading it, and both end up calling `this.addFormat`. But if multiple end up calling that function then `this.addFormat` throws an error: https://github.com/ipld/js-ipld/blob/021b4195b2c1254c323a9f370507fbaa0a42a112/src/index.js#L65-L76 The solution is a basic software transactional memory (STM) idea: If your reads are invalidated during your transaction, retry the transaction. In its purest form an STM solution would mean: ```js async getFormat (codec) { // TODO vmx 2019-01-24: Once all CIDs support accessing the codec code // instead of the name, remove this part if (typeof codec === 'string') { codec = multicodec.getCodeFromName(codec) } if (this.resolvers[codec]) { return this.resolvers[codec] } // If not supported, attempt to dynamically load this format const format = await this.loadFormat(codec) if (!this.resolvers[codec]) { // detect read invalidation return getFormat(codec) // retry } return format } ``` But we can manually inline the `getFormat` call and slightly improve the if-condition to be more readable and we end up with the code in this PR.
- Loading branch information