Last active
January 23, 2018 03:11
-
-
Save chux0519/c6ab2a4bde6061b0333a94c1b307a46a to your computer and use it in GitHub Desktop.
task-execution-limiter examples, paste code to http://requirebin.com to see result
This file contains 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 {TaskExecutionLimiter, buildTaskExecutionLimiter, buildWithLimit} = require('task-execution-limiter') | |
const console = require('consoleit') | |
const case1 = () => { | |
console.log('=> case 1: Usage of `TaskExecutionLimiter.schedule`') | |
// Using TaskExecutionLimiter class | |
// schedule method | |
const limiter = new TaskExecutionLimiter({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1, | |
concurrency: Infinity, // concurrency | |
queueLength: Infinity // queue length | |
}) | |
const now = Date.now() | |
const tasks = [ | |
limiter.schedule(() => 'a'), // function of schema: () => str | |
limiter.schedule(1), // Number | |
limiter.schedule(() => Promise.resolve('b')) // function of schema: () => Promise | |
] | |
return Promise.all(tasks).then(results => { | |
console.log(Number( | |
((Date.now() - now) / 1000).toFixed() // output: 2, (tasks.length - 1) seconds | |
)) | |
console.log(results) // output ['a', 1, 'b'] | |
}) | |
// output: | |
// 2 | |
// [ 'a', 1, 'b' ] | |
} | |
const case2 = () => { | |
console.log('=> case 2: Usage of `TaskExecutionLimiter.withLimit`') | |
// Using TaskExecutionLimiter class | |
// withLimit method | |
const limiter = new TaskExecutionLimiter({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1, | |
concurrency: Infinity, // concurrency | |
queueLength: Infinity // queue length | |
}) | |
const echo = (n) => { | |
return Promise.resolve(n) | |
} | |
const withLimitEcho = limiter.withLimit(echo) | |
const now = Date.now() | |
const tasks = ['a', 1, 'b'].map(each => withLimitEcho(each)) | |
return Promise.all(tasks).then(results => { | |
console.log(Number( | |
((Date.now() - now) / 1000).toFixed() // output: 2, (tasks.length - 1) seconds | |
)) | |
console.log(results) // output ['a', 1, 'b'] | |
}) | |
// output: | |
// 2 | |
// [ 'a', 1, 'b' ] | |
} | |
const case3 = () => { | |
console.log('=> case 3: Situation of overflow') | |
// Using TaskExecutionLimiter class | |
// setting length of queue to 1 | |
const limiter = new TaskExecutionLimiter({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1, | |
concurrency: Infinity, // concurrency | |
queueLength: 1 // queue length | |
}) | |
// will reject when overflow | |
const tasks = [ | |
// task was taked at once, queue will be empty | |
// timer started | |
// will output: 1 | |
limiter.schedule(1), | |
// timer stoped to limit the rate, it will restart in about `interval`ms | |
// queue is full now | |
// will output: 2 | |
limiter.schedule(2), | |
// will overflow | |
limiter.schedule(3).catch(console.error) // overflow, error: Queue will be overflowed, now drop the task: .... | |
] | |
return Promise.all(tasks).then(console.log).catch(console.error) | |
// output | |
// Error: Queue will be overflowed, now drop the task: 3 ... | |
// [ 1, 2, undefined ] | |
} | |
const case4 = () => { | |
console.log('=> case 4: Handle overflow') | |
// Using TaskExecutionLimiter class | |
// setting length of queue to 1 | |
// and modify the overflow handler | |
const limiter = new TaskExecutionLimiter({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1, | |
concurrency: Infinity, // concurrency | |
queueLength: 1, // queue length | |
queueOverflowHandler: function defaultQueueOverflowHandler (q, item) { | |
const [head, ...rest] = q | |
if (head.reject && head.task) head.reject(new Error(`Queue will be overflowed, now drop the task: ${head.task}`)) | |
return [...rest, item] | |
} | |
}) | |
// will ignroed head when overflow | |
const tasks = [ | |
// task was taked at once, queue will be empty | |
// timer started | |
// will output: 1 | |
limiter.schedule(1).catch(console.error), | |
// timer stoped to limit the rate, it will restart in about `interval`ms | |
// queue is full now | |
// output nothing | |
limiter.schedule(2).catch(console.error), | |
// added, and limiter.schedule(2) will be ignored | |
// will output: 3 | |
limiter.schedule(3).catch(console.error) | |
] | |
return Promise.all(tasks).then(console.log).catch(console.error) | |
// output | |
// Error: Queue will be overflowed, now drop the task: 2 ... | |
// [ 1, undefined, 3 ] | |
} | |
const case5 = () => { | |
console.log('=> case 5: Usage of `buildTaskExecutionLimiter`') | |
const limiter = buildTaskExecutionLimiter({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1, | |
concurrency: Infinity, // concurrency | |
queueLength: Infinity // queue length | |
}) | |
const now = Date.now() | |
const tasks = [ | |
limiter(Promise.resolve('a')), // Promise | |
limiter(1), // Number | |
limiter(() => Promise.resolve('b')) // function of schema: () => Promise | |
] | |
return Promise.all(tasks).then(results => { | |
console.log(Number( | |
((Date.now() - now) / 1000).toFixed() // output: 2, (tasks.length - 1) seconds | |
)) | |
console.log(results) // output ['a', 1, 'b'] | |
}) | |
// output: | |
// 2 | |
// [ 'a', 1, 'b' ] | |
} | |
const case6 = () => { | |
console.log('=> case 5: Usage of `buildWithLimit`') | |
// Using buildWithLimit function | |
const withLimit = buildWithLimit({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1, | |
concurrency: Infinity, // concurrency | |
queueLength: Infinity // queue length | |
}) | |
const echo = (n) => { | |
return Promise.resolve(n) | |
} | |
const withLimitEcho = withLimit(echo) | |
const now = Date.now() | |
const tasks = ['a', 1, 'b'].map(each => withLimitEcho(each)) | |
return Promise.all(tasks).then(results => { | |
console.log(Number( | |
((Date.now() - now) / 1000).toFixed() // output: 2, (tasks.length - 1) seconds | |
)) | |
console.log(results) // output ['a', 1, 'b'] | |
}) | |
// output: | |
// 2 | |
// [ 'a', 1, 'b' ] | |
} | |
const case7 = () => { | |
console.log('=> case 7: Given limit of decimals') | |
// limit with decimal | |
const withLimit = buildWithLimit({ | |
interval: 1000, // rate limit: one task per second | |
limit: 1.5, | |
concurrency: Infinity, // concurrency | |
queueLength: Infinity // queue length | |
}) | |
let now = Date.now() | |
let number = 0 | |
const handler = () => { | |
const t = Number( | |
((Date.now() - now) / 1000).toFixed() | |
) | |
number += 1 | |
console.log(`task ${number}: start at ${t}s`) | |
return t | |
} | |
const withLimitHandler = withLimit(handler) | |
const tasks = [ | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler(), | |
withLimitHandler() | |
] | |
// Simulate 1.5 tasks per second by alternately executing 1 task and 2 tasks per second | |
return Promise.all(tasks).then(console.log).catch(console.error) | |
} | |
case1() | |
.then(case2) | |
.then(case3) | |
.then(case4) | |
.then(case5) | |
.then(case6) | |
.then(case7) | |
.then(() => console.log('end')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment