Last active
July 5, 2019 10:53
-
-
Save arzmir/573cd7e0951528bc8905fe3cbac1a83f to your computer and use it in GitHub Desktop.
Problems with Electron, wait-on package, app.ready, event queue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const waitOn = require('wait-on'); | |
const Poller = require('./electron/Poller'); | |
console.time(':'); | |
const waitonCaller = () => { | |
return new Promise((resolve, reject) => { | |
try { | |
waitOn( | |
{ | |
resources: ['http://localhost:8999/health'], | |
delay: 500, | |
interval: 250, | |
timeout: 2000, | |
reverse: true, | |
log: true, | |
verbose: true, | |
}, | |
() => resolve('yay') | |
); | |
} catch (err) { | |
reject(err); | |
} | |
}); | |
}; | |
const pollerCaller = async () => { | |
const opts = { | |
expectingResponse: false, | |
startupDelay: 500, | |
pollingInterval: 250, | |
timesToPoll: 6, | |
}; | |
const result = await new Poller('http://localhost:8999/health', opts).execute(); | |
return result; | |
}; | |
(async () => { | |
console.timeLog(':', 'Pre waitOn'); | |
await waitonCaller(); | |
// await pollerCaller(); | |
console.timeLog(':', 'Post waitOn'); | |
})(); | |
process.on('beforeExit', () => { | |
console.timeLog(':', 'Elapsed time.'); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const axios = require('axios'); | |
const defaultOptions = { | |
axiosTimeout: 900, | |
chosenLogger: console.log, | |
expectingResponse: true, | |
pollingInterval: 1000, | |
startUpDelay: 1000, | |
timesToPoll: 5, | |
silent: false, | |
}; | |
class Poller { | |
constructor(url, suppliedOptions = {}) { | |
const options = { ...defaultOptions, ...suppliedOptions }; | |
this.url = url; | |
this.promises = []; | |
this.timeouts = []; | |
Object.entries(options).forEach(([key, value]) => { | |
if (Poller.MIN_VALUES[key]) { | |
this[key] = Math.min(Math.max(Poller.MIN_VALUES[key], value), Poller.MAX_VALUES[key]); | |
} else { | |
this[key] = value; | |
} | |
}); | |
this.source = axios.CancelToken.source(); | |
this.axiosClient = axios.create({ | |
timeout: this.axiosTimeout, | |
baseURL: this.url, | |
headers: { 'Access-Control-Allow-Origin': '*' }, | |
cancelToken: this.source.token, | |
}); | |
} | |
cancelRemainingRequests(current) { | |
this.source.cancel(); | |
this.timeouts.forEach((timeout, idx) => { | |
if (idx !== current) { | |
clearTimeout(timeout); | |
delete this.timeouts[idx]; | |
} | |
}); | |
this.promises.forEach((_, idx) => { | |
if (idx !== current) { | |
this.promises[idx].reject(); | |
delete this.promises[idx]; | |
} | |
}); | |
} | |
caller(resolve, reject, i) { | |
const time = Math.floor(new Date() - this.startTime); | |
if (!this.silent) this.chosenLogger(`Executing ${i}. call..`, `[${time} ms]`); | |
return this.axiosClient | |
.get() | |
.then(() => { | |
this.logForPoll(true, this.expectingResponse, i); | |
if (this.expectingResponse === true) { | |
this.cancelRemainingRequests(i); | |
resolve({ | |
success: true, | |
message: `Resource responded on poll #${i}`, | |
elapsedTime: `${Math.floor(new Date() - this.startTime)}ms`, | |
}); | |
} else if (i === this.timesToPoll) { | |
reject({ | |
success: false, | |
message: `All ${i} polls completed without success.`, | |
elapsedTime: `${Math.floor(new Date() - this.startTime)}ms`, | |
}); | |
} | |
}) | |
.catch(error => { | |
if (axios.isCancel(error) === false) { | |
this.logForPoll(false, this.expectingResponse, i); | |
if (this.expectingResponse === false) { | |
this.cancelRemainingRequests(i); | |
resolve({ | |
success: true, | |
message: `Resource stopped responding on poll #${i}`, | |
elapsedTime: `${Math.floor(new Date() - this.startTime)}ms`, | |
}); | |
} else if (i === this.timesToPoll) { | |
reject({ | |
success: false, | |
message: `All ${i} polls completed without success.`, | |
elapsedTime: `${Math.floor(new Date() - this.startTime)}ms`, | |
}); | |
} | |
} | |
}); | |
} | |
logForPoll(gotResponse, expectingResponse, i) { | |
const time = Math.floor(new Date() - this.startTime); | |
if (!this.silent) { | |
if (expectingResponse) { | |
if (gotResponse) { | |
this.chosenLogger(`Received response as expected on poll #${i}. Resolving poller...`, `[${time} ms]`); | |
} else { | |
this.chosenLogger(`Didn't receive response yet on poll #${i}. Continueing polling...`, `[${time} ms]`); | |
} | |
} else { | |
// eslint-disable-next-line no-lonely-if | |
if (gotResponse) { | |
this.chosenLogger(`Still received response on poll #${i}. Continueing polling...`, `[${time} ms]`); | |
} else { | |
this.chosenLogger(`Received error as expected for poll #${i}. Resolving poller...`, `[${time} ms]`); | |
} | |
} | |
} | |
} | |
execute() { | |
this.startTime = new Date(); | |
if (!this.silent) this.chosenLogger(`Checking ${this.url} expecting ${this.expectingResponse ? 'a' : 'no'} response.`); | |
for (let i = 1; i < this.timesToPoll + 1; i += 1) { | |
this.promises.push( | |
// eslint-disable-next-line no-loop-func | |
new Promise((resolve, reject) => { | |
const timeout = this.startUpDelay + this.pollingInterval * i; | |
this.timeouts.push(setTimeout(async () => this.caller(resolve, reject, i), timeout)); | |
}) | |
); | |
} | |
return Promise.race(this.promises) | |
.then(result => Promise.resolve(result)) | |
.catch(result => Promise.resolve(result)); | |
} | |
} | |
Poller.MIN_VALUES = { | |
axiosTimeout: 250, | |
pollingInterval: 100, | |
startUpDelay: 100, | |
timesToPoll: 1, | |
}; | |
Poller.MAX_VALUES = { | |
axiosTimeout: 30000, | |
pollingInterval: 10000, | |
startUpDelay: 30000, | |
timesToPoll: 25, | |
}; | |
module.exports = Poller; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment