Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

feat: dynamic format loading #178

Merged
merged 2 commits into from
Nov 9, 2018
Merged

feat: dynamic format loading #178

merged 2 commits into from
Nov 9, 2018

Conversation

alanshaw
Copy link
Member

@alanshaw alanshaw commented Nov 8, 2018

This backwards compatible PR allows missing IPLD formats to be loaded dynamically.

This follows on from the discussion here #164 (comment)

A new constructor option loadFormat allows users to asynchronously load an IPLD format. The IPLD instance will call this function automatically when it is requested to resolve a format that it doesn't currently understand.

This can re-enable lazy loading for IPLD modules in IPFS and also means that people who just want to add more resolvers can do so without having to depend directly on the defaults and pass them in as well.

It also removes a bunch of repeated "No resolver found for codec" blocks so the code is more DRYFTW \o/

This backwards compatible PR allows missing IPLD formats to be loaded dynamically.

This follows on from the discussion here #164 (comment)

A new constructor option `loadFormat` allows users to asynchronously load an IPLD format. The IPLD instance will call this function automatically when it is requested to resolve a format that it doesn't currently understand.

This can re-enable lazy loading for IPLD modules in IPFS and also means that people who just want to add _more_ resolvers can do so without having to depend directly on the defaults and pass them in as well.

License: MIT
Signed-off-by: Alan Shaw <[email protected]>
@ghost ghost assigned alanshaw Nov 8, 2018
@ghost ghost added the status/in-progress In progress label Nov 8, 2018
@alanshaw alanshaw requested a review from vmx November 8, 2018 16:11
@codecov
Copy link

codecov bot commented Nov 8, 2018

Codecov Report

Merging #178 into master will increase coverage by 4.34%.
The diff coverage is 95.91%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #178      +/-   ##
=========================================
+ Coverage   89.05%   93.4%   +4.34%     
=========================================
  Files           1       1              
  Lines         201     197       -4     
=========================================
+ Hits          179     184       +5     
+ Misses         22      13       -9
Impacted Files Coverage Δ
src/index.js 93.4% <95.91%> (+4.34%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4d7409e...f5fb929. Read the comment docs.

Copy link
Member

@vmx vmx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a great PR! That's really smart, thanks a lot. I've only minor comments/questions.

BTW: Thanks a lot, I had this on my todo list, but I certainly wouldn't have solved the problem in such a flexible way.


```js
const ipld = new Ipld({
loadFormat (codec, callback) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, I didn't know that this syntax is a things. It's nice to learn new things by code reviewing.

})

it('should fail to dynamically load format via loadFormat option', (done) => {
const errMsg = 'BOOM' + Date.now()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the Date.now()? I generally prefer tests that do the exact same across runs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I want to ensure the error that was thrown was the error that I threw. I'm asserting on the error message so I need a value that is not going to cause a false positive with any other error that could be thrown.

So, yes, I guess I could just use a static string but there's a tiny bit more risk of it causing a false possitive in the future than a value that is randomly generated.

In general I know that tests are not isolated from side effects, so I like to know my tests are dealing with their own unique data. As an example we share block stores across multiple tests and they don't clean up after themselves. By the way, I don't believe they should clean up and we can't guarantee that it'll happen (in the case of failures) or that unintentional side effects don't happen. Ideally we'd use a new block store for every test, but I appreciate that's not always practical....The point is, using randomly generated data is one way of better isolating tests from side effects caused by other tests.

A completely contrived example: I'm testing I can put a value with IPLD and I use a static value. Many weeks later someone adds a test before mine that puts that same value in the block store. Since the block store is shared, when my test runs the code somehow determines the value is already in the store and returns success. Same result, but it's a different code path that's being tested now, and maybe that's masking a error with the code path that writes to disk...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I'm happy to change if you disagree or would prefer!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation. It makes sense, happy to keep it that way.

const bs = new BlockService(repo)
const resolver = new IPLDResolver({ blockService: bs })

data = { now: Date.now() }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the Date.now()? I generally prefer tests that do the exact same across runs.


const IPLDResolver = require('../src')

module.exports = (repo) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add a test that a format is not dynamically loaded when it was already statically added?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Member

@vmx vmx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's so nice with a working CI :)

@vmx vmx merged commit 3630e76 into master Nov 9, 2018
@ghost ghost removed the status/in-progress In progress label Nov 9, 2018
@vmx vmx deleted the feat/dynamic-format-loading branch November 9, 2018 10:52
alanshaw pushed a commit to ipfs/js-ipfs that referenced this pull request Nov 9, 2018
This PR uses the new `loadFormat` option for IPLD to lazily require IPLD formats in order to reduce the startup time for the node.

If you're feeling like you've seen this before then, for reference:

The PR ipld/js-ipld#164 undid the work done in ipld/js-ipld#145 and ipld/js-ipld#178 re-enabled lazy loading.

License: MIT
Signed-off-by: Alan Shaw <[email protected]>
alanshaw pushed a commit to ipfs/js-ipfs that referenced this pull request Nov 12, 2018
This PR uses the new `loadFormat` option for IPLD to lazily require IPLD formats in order to reduce the startup time for the node.

If you're feeling like you've seen this before then, for reference:

The PR ipld/js-ipld#164 undid the work done in ipld/js-ipld#145 and ipld/js-ipld#178 re-enabled the ability to do so. This PR makes use of this new ability to lazy load the formats.

License: MIT
Signed-off-by: Alan Shaw <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants