mirror of
https://github.com/fluencelabs/dweb-transports
synced 2025-04-25 14:52:18 +00:00
v0.1.42 Improve behavior when cant reach gateway
This commit is contained in:
parent
f37a0562be
commit
77a66c1a54
21
README.md
21
README.md
@ -126,16 +126,17 @@ See [Dweb document index](./DOCUMENTINDEX.md) for a list of the repos that make
|
|||||||
|
|
||||||
### Release Notes
|
### Release Notes
|
||||||
|
|
||||||
* 0.1.33: Bug fixes; support for gatewayUrls (for dweb-mirror)
|
* 0.1.42: Better behavior when cant see gateway
|
||||||
* 0.1.35: package update (note wont work with latest versions of yjs or uglify)
|
* 0.1.41: Remove createReadStream for browser (it was added for node in 0.1.40), add fetch(url,opts,cb)
|
||||||
* 0.1.36: Made httptools accessable at Transports.httptools so it doesnt have to be separately 'require'd
|
|
||||||
* 0.1.37: IPFS - dont stop it if we didnt start it (were stopping via API)
|
|
||||||
* 0.1.37: Start move to unpromisify pattern v5
|
|
||||||
* 0.1.37: IPFS - updated to (significant) v0.34.0 API changes
|
|
||||||
* 0.1.38: httptools - adds retries
|
|
||||||
* 0.1.38: WOLK - added to the library
|
|
||||||
* 0.1.39: WOLK - updated wolk.js module to fix bugs
|
|
||||||
* 0.1.40: Bug fix in httpfetch({count=0}),
|
* 0.1.40: Bug fix in httpfetch({count=0}),
|
||||||
* 0.1.40: Added support for "seed" and tested in IPFS
|
* 0.1.40: Added support for "seed" and tested in IPFS
|
||||||
* 0.1.40: WOLK - moved to their production sys and master branch
|
* 0.1.40: WOLK - moved to their production sys and master branch
|
||||||
* 0.1.41: Remove createReadStream for browser (it was added for node in 0.1.40), add fetch(url,opts,cb)
|
* 0.1.39: WOLK - updated wolk.js module to fix bugs
|
||||||
|
* 0.1.38: httptools - adds retries
|
||||||
|
* 0.1.38: WOLK - added to the library
|
||||||
|
* 0.1.37: IPFS - dont stop it if we didnt start it (were stopping via API)
|
||||||
|
* 0.1.37: Start move to unpromisify pattern v5
|
||||||
|
* 0.1.37: IPFS - updated to (significant) v0.34.0 API changes
|
||||||
|
* 0.1.36: Made httptools accessable at Transports.httptools so it doesnt have to be separately 'require'd
|
||||||
|
* 0.1.35: package update (note wont work with latest versions of yjs or uglify)
|
||||||
|
* 0.1.33: Bug fixes; support for gatewayUrls (for dweb-mirror)
|
||||||
|
13
Transport.js
13
Transport.js
@ -92,7 +92,11 @@ class Transport {
|
|||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
supports(url, func) {
|
connected() {
|
||||||
|
// True if connected (status==STATUS_CONNECTED==0) should not need subclassing
|
||||||
|
return ! this.status;
|
||||||
|
}
|
||||||
|
supports(url, func) { //TODO-API
|
||||||
/*
|
/*
|
||||||
Determine if this transport supports a certain set of URLs and a func
|
Determine if this transport supports a certain set of URLs and a func
|
||||||
|
|
||||||
@ -111,6 +115,13 @@ class Transport {
|
|||||||
&& (!func || this.supportFunctions.includes(func)))
|
&& (!func || this.supportFunctions.includes(func)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validFor(url, func) { //TODO-API
|
||||||
|
// By default a transport can handle a url and a func if its connected and supports that url/func
|
||||||
|
// This shouldnt need subclassing, an exception is HTTP which only applies "connected" against urls heading for the gateway
|
||||||
|
return this.connected() && this.supports(url, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
p_rawstore(data, opts) {
|
p_rawstore(data, opts) {
|
||||||
/*
|
/*
|
||||||
Store a blob of data onto the decentralised transport.
|
Store a blob of data onto the decentralised transport.
|
||||||
|
@ -8,7 +8,7 @@ const stringify = require('canonical-json');
|
|||||||
|
|
||||||
|
|
||||||
defaulthttpoptions = {
|
defaulthttpoptions = {
|
||||||
urlbase: 'https://dweb.me:443'
|
urlbase: 'https://dweb.me'
|
||||||
};
|
};
|
||||||
|
|
||||||
servercommands = { // What the server wants to see to return each of these
|
servercommands = { // What the server wants to see to return each of these
|
||||||
@ -29,7 +29,7 @@ class TransportHTTP extends Transport {
|
|||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options); // These are now options.http
|
super(options); // These are now options.http
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.urlbase = options.urlbase;
|
this.urlbase = options.urlbase; // e.g. https://dweb.me
|
||||||
this.supportURLs = ['contenthash', 'http','https'];
|
this.supportURLs = ['contenthash', 'http','https'];
|
||||||
this.supportFunctions = ['fetch', 'store', 'add', 'list', 'reverse', 'newlisturls', "get", "set", "keys", "getall", "delete", "newtable", "newdatabase"]; //Does not support: listmonitor - reverse is disabled somewhere not sure if here or caller
|
this.supportFunctions = ['fetch', 'store', 'add', 'list', 'reverse', 'newlisturls', "get", "set", "keys", "getall", "delete", "newtable", "newdatabase"]; //Does not support: listmonitor - reverse is disabled somewhere not sure if here or caller
|
||||||
if (typeof window === "undefined") {
|
if (typeof window === "undefined") {
|
||||||
@ -86,6 +86,12 @@ class TransportHTTP extends Transport {
|
|||||||
url = url + (parmstr ? "?"+parmstr : "");
|
url = url + (parmstr ? "?"+parmstr : "");
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validFor(url, func) {
|
||||||
|
// Overrides Transport.prototype.validFor because HTTP's connection test is only really for dweb.me
|
||||||
|
// in particular this allows urls like https://be-api.us.archive.org
|
||||||
|
return (this.connected() || (url.protocol.startsWith("http") && ! url.href.startsWith(this.urlbase))) && this.supports(url, func);
|
||||||
|
}
|
||||||
// noinspection JSCheckFunctionSignatures
|
// noinspection JSCheckFunctionSignatures
|
||||||
async p_rawfetch(url, opts={}) {
|
async p_rawfetch(url, opts={}) {
|
||||||
/*
|
/*
|
||||||
@ -304,7 +310,7 @@ class TransportHTTP extends Transport {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
p_info() { return httptools.p_GET(`${this.urlbase}/info`); }
|
p_info() { return httptools.p_GET(`${this.urlbase}/info`, {retries: 5}); } // Try info, but dont wait more than approx 10secs
|
||||||
|
|
||||||
static async p_test(opts={}) {
|
static async p_test(opts={}) {
|
||||||
{console.log("TransportHTTP.test")}
|
{console.log("TransportHTTP.test")}
|
||||||
|
@ -61,14 +61,14 @@ class Transports {
|
|||||||
console.error("Transports.validFor called with invalid arguments: urls=", urls, "func=", func); // FOr debugging old calling patterns with [ undefined ]
|
console.error("Transports.validFor called with invalid arguments: urls=", urls, "func=", func); // FOr debugging old calling patterns with [ undefined ]
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (!(urls && urls.length > 0)) {
|
if (!(urls && urls.length > 0)) { // No url supplied we are just checking which transports support this function on no url.
|
||||||
return this._connected().filter((t) => (t.supports(undefined, func)))
|
return this._transports.filter((t) => (t.validFor(undefined, func)))
|
||||||
.map((t) => [undefined, t]);
|
.map((t) => [undefined, t]);
|
||||||
} else {
|
} else {
|
||||||
return [].concat(
|
return [].concat(
|
||||||
...urls.map((url) => typeof url === 'string' ? Url.parse(url) : url) // parse URLs once
|
...urls.map((url) => typeof url === 'string' ? Url.parse(url) : url) // parse URLs once
|
||||||
.map((url) =>
|
.map((url) =>
|
||||||
this._connected().filter((t) => (t.supports(url, func))) // [ t1, t2 ]
|
this._transports.filter((t) => (t.validFor(url, func))) // [ t1, t2 ]
|
||||||
.map((t) => [url, t]))); // [[ u, t1], [u, t2]]
|
.map((t) => [url, t]))); // [[ u, t1], [u, t2]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,34 +338,34 @@ class Transports {
|
|||||||
wanturl True if want the URL of the stream (for service workers)
|
wanturl True if want the URL of the stream (for service workers)
|
||||||
returns: f(opts) => stream returning bytes from opts.start || start of file to opts.end-1 || end of file
|
returns: f(opts) => stream returning bytes from opts.start || start of file to opts.end-1 || end of file
|
||||||
*/
|
*/
|
||||||
|
// Find all the transports that CAN support this request
|
||||||
let tt = this.validFor(urls, "createReadStream", {}); //[ [Url,t],[Url,t]] // Can pass options TODO-STREAM support options in validFor
|
let tt = this.validFor(urls, "createReadStream", {}); //[ [Url,t],[Url,t]] // Can pass options TODO-STREAM support options in validFor
|
||||||
if (!tt.length) {
|
if (!tt.length) {
|
||||||
debug("Opening stream to %o failed: no transports available", urls);
|
debug("Opening stream from %o failed: no transports available", urls);
|
||||||
throw new errors.TransportError("Transports.p_createReadStream cant find any transport for urls: " + urls);
|
throw new errors.TransportError("Transports.p_createReadStream cant find any transport for urls: " + urls);
|
||||||
}
|
}
|
||||||
//With multiple transports, it should return when the first one returns something.
|
//With multiple transports, it should return when the first one returns something.
|
||||||
let errs = [];
|
let errs = [];
|
||||||
// Until we have transport ordering, try randomly TODO Transport ordering
|
|
||||||
|
|
||||||
//Debugging: preferredTransports = [] // ["WEBTORRENT", "IPFS", "HTTP"];
|
// Select first from preferredTransports in the order presented, then the rest at random
|
||||||
tt.sort((a,b) =>
|
tt.sort((a,b) =>
|
||||||
((preferredTransports.indexOf(a[1].name)+1) || 999+Math.random()) - ((preferredTransports.indexOf(b[1].name)+1) || 999+Math.random())
|
((preferredTransports.indexOf(a[1].name)+1) || 999+Math.random()) - ((preferredTransports.indexOf(b[1].name)+1) || 999+Math.random())
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const [url, t] of tt) {
|
for (const [url, t] of tt) {
|
||||||
try {
|
try {
|
||||||
debug("Opening stream to %s via %s", url.href, t.name);
|
debug("Opening stream from %s via %s", url.href, t.name);
|
||||||
let res = await t.p_f_createReadStream(url, {wanturl} );
|
let res = await t.p_f_createReadStream(url, {wanturl} );
|
||||||
debug("Opening stream to %s via %s succeeded", url.href, t.name);
|
debug("Opening stream from %s via %s succeeded", url.href, t.name);
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errs.push(err);
|
errs.push(err);
|
||||||
debug("Opening stream to %s via %s failed: %s", url.href, t.name, err.message);
|
debug("Opening stream from %s via %s failed: %s", url.href, t.name, err.message);
|
||||||
// Don't throw anything here, loop round for next, only throw if drop out bottom
|
// Don't throw anything here, loop round for next, only throw if drop out bottom
|
||||||
//TODO-MULTI-GATEWAY potentially copy from success to failed URLs.
|
//TODO-MULTI-GATEWAY potentially copy from success to failed URLs.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug("Opening stream to %o failed on all transports", urls);
|
debug("Opening stream from %o failed on all transports", urls);
|
||||||
throw new errors.TransportError(errs.map((err)=>err.message).join(', ')); //Throw err with combined messages if none succeed
|
throw new errors.TransportError(errs.map((err)=>err.message).join(', ')); //Throw err with combined messages if none succeed
|
||||||
}
|
}
|
||||||
static createReadStream(urls, opts, cb) {
|
static createReadStream(urls, opts, cb) {
|
||||||
|
4
dist/dweb-transports-bundle.js
vendored
4
dist/dweb-transports-bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -42,7 +42,7 @@ async function loopfetch(req, ms, count, what) {
|
|||||||
lasterr = err;
|
lasterr = err;
|
||||||
debug("Delaying %s by %d ms because %s", what, ms, err.message);
|
debug("Delaying %s by %d ms because %s", what, ms, err.message);
|
||||||
await new Promise(resolve => {setTimeout(() => { resolve(); },ms)})
|
await new Promise(resolve => {setTimeout(() => { resolve(); },ms)})
|
||||||
ms = ms*(1+Math.random()); // Spread out delays incase all requesting same time
|
ms = Math.floor(ms*(1+Math.random())); // Spread out delays incase all requesting same time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.warn("loopfetch of",what,"failed");
|
console.warn("loopfetch of",what,"failed");
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
"url": "https://github.com/internetarchive/dweb-transports/issues"
|
"url": "https://github.com/internetarchive/dweb-transports/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"canonical-json": "latest",
|
"canonical-json": "^0.0.4",
|
||||||
"cids": "^0.5.7",
|
"cids": "^0.5.7",
|
||||||
|
"debug": "^4.1.1",
|
||||||
"gun": "^0.9.9999991",
|
"gun": "^0.9.9999991",
|
||||||
"ipfs": "^0.34.4",
|
"ipfs": "^0.34.4",
|
||||||
"ipfs-http-client": "^29.1.1",
|
"ipfs-http-client": "^29.1.1",
|
||||||
@ -52,5 +53,5 @@
|
|||||||
"test": "cd src; node ./test.js",
|
"test": "cd src; node ./test.js",
|
||||||
"help": "echo 'test (test it)'; echo 'build (creates dweb-transports-bundle)'"
|
"help": "echo 'test (test it)'; echo 'build (creates dweb-transports-bundle)'"
|
||||||
},
|
},
|
||||||
"version": "0.1.41"
|
"version": "0.1.42"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user