Skip to content

Commit

Permalink
libresilient: run fetch and alt-fetch in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
link2xt committed Oct 19, 2024
1 parent 14cdd83 commit 6cf8b82
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 12 deletions.
34 changes: 22 additions & 12 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
{
"plugins": [{
"name": "fetch"
},
"plugins": [
{
"name": "cache"
"name": "any-of",
"uses": [
{
"name": "fetch"
},
{
"name": "delay",
"defaultDelay": 5000,
"uses": [
{
"name": "alt-fetch",
"endpoints": ["https://deltachat.github.io/deltachat-pages/"]
}
]
}
]
},
{
"name": "alt-fetch",
"endpoints": [
"https://deltachat.github.io/deltachat-pages/"
]
"name": "cache"
}
],
"stillLoadingTimeout": 0,
"loggedComponents": ["service-worker", "fetch", "cache", "alt-fetch"]
],
"defaultPluginTimeout": 300000,
"stillLoadingTimeout": 0,
"loggedComponents": ["service-worker", "fetch", "cache", "alt-fetch"]
}

59 changes: 59 additions & 0 deletions plugins/any-of/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* ========================================================================= *\
|* === Any-of: running multiple plugins simultaneously === *|
\* ========================================================================= */

/**
* this plugin does not implement any push method
*/

// no polluting of the global namespace please
(function(LRPC){
// this never changes
const pluginName = "any-of"
LRPC.set(pluginName, (LR, init={})=>{

/*
* plugin config settings
*/

// sane defaults
let defaultConfig = {
// list of plugins to run simultaneously
uses: [{
name: "alt-fetch"
},{
name: "gun-ipfs"
}]
}

// merge the defaults with settings from LibResilientConfig
let config = {...defaultConfig, ...init}

// reality check: if no wrapped plugin configured, complain
if (config.uses.length < 1) {
throw new Error("No wrapped plugins configured!")
}

/**
* getting content using Promise.any() on all configured wrapped plugins
*/
let fetchContent = (url, init={}) => {
LR.log(pluginName, `using: [${config.uses.map(p=>p.name).join(', ')}]!`)
return Promise.any(
config.uses.map(p=>p.fetch(url, init))
)
}

// and add ourselves to it
// with some additional metadata
return {
name: pluginName,
description: `Running simultaneously: [${config.uses.map(p=>p.name).join(', ')}]`,
version: 'COMMIT_UNKNOWN',
fetch: fetchContent,
uses: config.uses
}

})
// done with not polluting the global namespace
})(LibResilientPluginConstructors)
86 changes: 86 additions & 0 deletions plugins/delay/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* ========================================================================= *\
|* === Delay plugin === *|
\* ========================================================================= */

/**
* this plugin does not implement any push method
*/

// no polluting of the global namespace please
(function(LRPC){
// this never changes
const pluginName = "delay"
LRPC.set(pluginName, (LR, init={})=>{

/*
* plugin config settings
*/

// sane defaults
let defaultConfig = {
// array of two-element arrays
// ["/regex_match/", <slowdown in ms>]
// first match wins
delay: [],

// default delay, in ms
defaultDelay: 1000,

// plugin to wrap, regular fetch by default
uses: [{
name: "fetch"
}]
}

// merge the defaults with settings from init
let config = {...defaultConfig, ...init}

// reality check: if no wrapped plugin configured, or more than one, complain
if (config.uses.length != 1) {
throw new Error(`Expected exactly one plugin to wrap, but ${config.uses.length} configured.`)
}

/**
* getting content using regular HTTP(S) fetch()
*/
let fetchContent = (url, init={}) => {
LR.log(pluginName, `delayed retrieval: ${url}`)
// we really want to make fetch happen, Regina!
// TODO: this change should *probably* be handled on the Service Worker level
init.cache = 'reload'

// establish the default delay
let impose_delay = config.defaultDelay
LR.log(pluginName, `default delay: ${impose_delay}`)

// see if we have any specific delay rule that matches
// first match wins
for (sp of config.delay) {
LR.log(pluginName, `checking delay rule: ${sp}`)
let re = new RegExp(sp[0])
if (url.search(re) > -1) {
LR.log(pluginName, `delay rule matched: ${sp[0]}, delay set to: ${sp[1]}`)
impose_delay = sp[1]
break;
}
}

// wait a bit and run the first wrapped plugin's fetch()
return promiseTimeout(impose_delay, true)[0]
.then(() => {
return config.uses[0].fetch(url, init)
})
}

// return the plugin
return {
name: pluginName,
description: 'Configurable delay!',
version: 'COMMIT_UNKNOWN',
fetch: fetchContent,
uses: config.uses
}

})
// done with not polluting the global namespace
})(LibResilientPluginConstructors)

0 comments on commit 6cf8b82

Please sign in to comment.