-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement client fallback mechanism #16
Conversation
@guanzo also enabled eslint + jsdoc type checking |
src/index.js
Outdated
// we use this to checkpoint at which chunk a request failed. | ||
// this is temporary until range requests are supported. | ||
let byteCountCheckpoint = 0 | ||
for (const origin of this.nodes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retrying 100 times seems a bit overkill, especially if the error is consistent and will throw on every attempt. Like there's something wrong with the DAG itself and not the L1. I think we should start smaller at like 10 and see how it goes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah agreed, was thinking about that as well.
Wondering if there are errors that we should handle, like if the js client verification fails due to some js error then it will probably fail for every fallback node regardless
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah there'll be a class of errors where we should just bail instead of retrying. i think "file not found" is one of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a limit to the amount we can fallback. I do think some errors should be bailed right away but i think id save that for another PR.
Im also worried about perf with error matching mid request. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perf shouldn't be an issue unless the error list is huge, like 10k+.
Co-authored-by: Diego Rodríguez Baquero <[email protected]>
* Abort on error (#19) * feat: use controller from options if exists. abort fetch if error occurs. * test: check if external abort controller is used * build: move build output to dist/ folder * fix: newline * 0.1.1 * Build exports (#20) * chore: rename file * feat: add new entrypoint with exports. Switch Saturn to named export * build: expose entire module instead of just the default export * docs: update README * 0.2.0 * feat: include worker scopes when checking for browser runtime (#21) * 0.3.0 --------- Co-authored-by: Eric Guan <[email protected]>
* @param {import('./storage/index.js').Storage} [opts.storage] | ||
*/ | ||
constructor (opts = {}) { | ||
this.opts = Object.assign({}, { | ||
clientId: randomUUID(), | ||
cdnURL: 'saturn.ms', | ||
logURL: 'https://twb3qukm2i654i3tnvx36char40aymqq.lambda-url.us-west-2.on.aws/', | ||
orchURL: 'https://orchestrator.strn.pl/nodes?maxNodes=100', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guanzo I want to clean this up a little by having those URLs in one place and they get imported here. You cool with that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree on this if possible -- having these really weird URLs hardcoded right in the code is a bit odd. I might this a private static class readonly var "defaultConfig" or something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to keep our auth URL at least a private var?
Doesn't completely hide it but at least makes it harder for someone to find it and use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These kinds of URL config vars should typically be env vars injected during the build process.
When you guys say "private var" do you mean https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes thats correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally LGTM. and overall, awsome PR.
everything is a suggestion but I do think you have a minor bug in FetchContentWithFallback when there is byte overlap. Definitely respond to my comment there before you merge
.eslintrc
Outdated
@@ -0,0 +1,14 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: if we're going to have this, we should remove the config from package.json: https://github.com/filecoin-saturn/js-client/pull/16/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519L43
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added the config to the package.json. Didn't notice it was there in the first place, so I just removed the .eslintrc and ported over the updated config.
* @param {import('./storage/index.js').Storage} [opts.storage] | ||
*/ | ||
constructor (opts = {}) { | ||
this.opts = Object.assign({}, { | ||
clientId: randomUUID(), | ||
cdnURL: 'saturn.ms', | ||
logURL: 'https://twb3qukm2i654i3tnvx36char40aymqq.lambda-url.us-west-2.on.aws/', | ||
orchURL: 'https://orchestrator.strn.pl/nodes?maxNodes=100', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree on this if possible -- having these really weird URLs hardcoded right in the code is a bit odd. I might this a private static class readonly var "defaultConfig" or something
src/client.js
Outdated
@@ -33,13 +40,15 @@ export class Saturn { | |||
} | |||
|
|||
this.logs = [] | |||
this.storage = this.opts.storage || memoryStorage() | |||
this.nodes = [] | |||
this.nodesListKey = 'saturn-nodes' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this ever going to change? if not, I'd again just make it a static readonly var.
* @returns {URL|string} | ||
*/ | ||
export function parseUrl (url) { | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guanzo had to add this try catch here because when testing in the browser, process
is not defined. Seems like webpack's environment plugin doesn't make process
accessible in libraries that you import from. This parseUrl
function is only for testing though and is temporary so think this is fine for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why's it being imported by the browser-client if its only used for testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry its not only for testing, parseUrl is used within the js-client code. Im was just saying the reason it exists because the mock tests don't accept URL
objects in fetch
so had to add this to make them run.
Changes:
Adding a managed nodes list for the client:
nodes
array that the client manages.storage
option to the client which can be injected as long as it matches the definedStorage
interface.Storage
implementation that uses IndexedDb. This will be the first storage implementation as this is the only one that service workers support immediately. More can be added as needed.Implementing a test suite:
wsj
library. This allows for more robust testing locally.