Skip to content

Instantly share code, notes, and snippets.

@chux0519
Last active January 23, 2018 03:11
Show Gist options
  • Save chux0519/c6ab2a4bde6061b0333a94c1b307a46a to your computer and use it in GitHub Desktop.
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
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