d4c-queue
Version:
A task queue executes tasks sequentially or concurrently. Wrap an async/promise-returning/sync function as a queue-ready async function for easy reusing. Support passing arguments/getting return value, @synchronized/@concurrent decorator, Node.js/Browser.
905 lines • 67.3 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import autobind from 'autobind-decorator';
import test from 'ava';
import { concurrent, D4C, ErrMsg, QConcurrency, synchronized } from './D4C';
const fixture = ['hello'];
const fixture2 = 'world';
const queueTag = 'queue1';
const funcAsync = (input, input2) => __awaiter(void 0, void 0, void 0, function* () {
return input[0] + input2;
});
const funcSync = (input, input2) => {
return input[0] + input2;
};
const funcPromise = (input, input2) => {
return Promise.resolve(input[0] + input2);
};
const timeout = (seconds, target) => {
return new Promise((resolve, _) => setTimeout(() => {
if ((target === null || target === void 0 ? void 0 : target.str) != undefined && (target === null || target === void 0 ? void 0 : target.str) != null) {
target.str += seconds;
}
resolve();
}, seconds * 100));
};
const timeoutError = (seconds, result) => {
return new Promise((_, reject) => setTimeout(() => {
reject(result);
}, seconds * 100));
};
const immediateFun = (seconds, target) => {
target.str += seconds;
};
const immediateFunPromise = (seconds, target) => {
target.str += seconds;
return Promise.resolve();
};
test('Class usage: test concurrency', (t) => __awaiter(void 0, void 0, void 0, function* () {
let TestController = class TestController {
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
instanceTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout2(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
instanceTimeout2(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
random(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
concurrent
], TestController.prototype, "instanceTimeout", null);
__decorate([
concurrent({ tag: '2' })
], TestController.prototype, "instanceTimeout2", null);
__decorate([
synchronized({ tag: '3' })
], TestController.prototype, "random", null);
__decorate([
concurrent
], TestController, "staticTimeout", null);
__decorate([
concurrent({ tag: '2' })
], TestController, "staticTimeout2", null);
TestController = __decorate([
QConcurrency([
{ limit: 100, isStatic: true },
{ limit: 100, isStatic: false },
{ limit: 1, isStatic: true, tag: '2' },
{ limit: 1, tag: '2' },
])
], TestController);
// test: concurrency on static method, and use default tag
let test = { str: '' };
yield Promise.all([
TestController.staticTimeout(0.5, test),
TestController.staticTimeout(0.1, test),
]);
t.is(test.str, '0.10.5');
// test: concurrency on static method,
test = { str: '' };
yield Promise.all([
TestController.staticTimeout2(0.5, test),
TestController.staticTimeout2(0.1, test),
]);
t.is(test.str, '0.50.1');
// test: concurrency on instance method, and use default tag
const testController = new TestController();
test = { str: '' };
yield Promise.all([
testController.instanceTimeout(0.5, test),
testController.instanceTimeout(0.1, test),
]);
t.is(test.str, '0.10.5');
// test: concurrency on instance method
test = { str: '' };
yield Promise.all([
testController.instanceTimeout2(0.5, test),
testController.instanceTimeout2(0.1, test),
]);
t.is(test.str, '0.50.1');
// test: no use class decorator so @concurrent will use default @concurrency Infinity
class TestController2 {
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
}
__decorate([
concurrent
], TestController2, "staticTimeout", null);
test = { str: '' };
yield Promise.all([
TestController2.staticTimeout(0.5, test),
TestController2.staticTimeout(0.1, test),
]);
t.is(test.str, '0.10.5');
let TestController3 = class TestController3 {
static staticTimeoutNoDecorator(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
instanceTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout2(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
instanceTimeout2(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
concurrent
], TestController3.prototype, "instanceTimeout", null);
__decorate([
concurrent({ tag: '2' })
], TestController3.prototype, "instanceTimeout2", null);
__decorate([
concurrent
], TestController3, "staticTimeout", null);
__decorate([
concurrent({ tag: '2' })
], TestController3, "staticTimeout2", null);
TestController3 = __decorate([
QConcurrency([
{ limit: 1, isStatic: true },
{ limit: 1, isStatic: false },
{ limit: 1, isStatic: true, tag: '2' },
{ limit: 1, isStatic: false, tag: '2' },
])
], TestController3);
// Test: applying @classConcurrency but testing method not decorated will not be affected
test = { str: '' };
yield Promise.all([
TestController3.staticTimeoutNoDecorator(0.5, test),
TestController3.staticTimeoutNoDecorator(0.1, test),
]);
t.is(test.str, '0.10.5');
// Test: different queues are isolated with each other
const testController3 = new TestController3();
test = { str: '' };
yield Promise.all([
TestController.staticTimeout(0.5, test),
testController.instanceTimeout(0.4, test),
TestController.staticTimeout2(0.3, test),
testController.instanceTimeout2(0.2, test),
]);
t.is(test.str, '0.20.30.40.5');
/** @classConcurrency tries to setup default queue's concurrency but is conflicted with synchronized (implicitly concurrency =1) */
let error = null;
try {
let TestController4 = class TestController4 {
static staticTimeoutNoDecorator(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
synchronized
], TestController4, "staticTimeout", null);
TestController4 = __decorate([
QConcurrency([{ limit: 1, isStatic: true }])
], TestController4);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.ClassAndMethodDecoratorsIncompatible);
/** for test coverage */
error = null;
try {
let TestController5 = class TestController5 {
static staticTimeoutNoDecorator(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
synchronized
], TestController5, "staticTimeout", null);
TestController5 = __decorate([
QConcurrency([{ limit: 1, isStatic: true, tag: '2' }])
], TestController5);
}
catch (err) {
error = err;
}
t.is(error, null);
/** for test coverage */
error = null;
try {
let TestController6 = class TestController6 {
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
concurrent
], TestController6, "staticTimeout", null);
TestController6 = __decorate([
QConcurrency([{ limit: 1, isStatic: true, tag: '2' }])
], TestController6);
}
catch (err) {
error = err;
}
t.is(error, null);
/** for test coverage */
error = null;
try {
let TestController7 = class TestController7 {
staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
synchronized
], TestController7.prototype, "staticTimeout", null);
TestController7 = __decorate([
QConcurrency([{ limit: 1, tag: '2' }])
], TestController7);
}
catch (err) {
error = err;
}
t.is(error, null);
/** for test coverage */
error = null;
try {
let TestController8 = class TestController8 {
staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
TestController8 = __decorate([
QConcurrency([
{ limit: 1, tag: '2' },
{ limit: 1, tag: '3', isStatic: true },
])
], TestController8);
}
catch (err) {
error = err;
}
t.is(error, null);
/** for the same tag queue, @concurrent & @synchronized can not be applied both */
error = null;
try {
let TestController9 = class TestController9 {
static staticTimeoutNoDecorator(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static staticTimeout2(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
__decorate([
synchronized
], TestController9, "staticTimeout", null);
__decorate([
concurrent
], TestController9, "staticTimeout2", null);
TestController9 = __decorate([
QConcurrency([{ limit: 1, isStatic: true }])
], TestController9);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.TwoDecoratorsIncompatible);
/** @classConcurrency' parameters should be an array */
error = null;
try {
let TestController10 = class TestController10 {
staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
TestController10 = __decorate([
QConcurrency({ limit: 1, tag: '2' })
], TestController10);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidClassDecoratorParameter);
/** limit should be a number */
error = null;
try {
let TestController11 = class TestController11 {
staticTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
};
TestController11 = __decorate([
QConcurrency([null, { limit: '3' }])
], TestController11);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidClassDecoratorParameter);
}));
test('Instance usage: test concurrency', (t) => __awaiter(void 0, void 0, void 0, function* () {
/** Fixme: dummy cases for code coverage */
let d4c = new D4C([null]);
d4c = new D4C([{}]);
d4c.setConcurrency(null);
/** default queue: concurrency 100 test */
let test = { str: '' };
d4c = new D4C([{ concurrency: { limit: 100 } }]);
let fn1 = d4c.wrap(timeout);
let fn2 = d4c.wrap(immediateFun);
let fn3 = d4c.wrap(immediateFunPromise);
yield Promise.all([
fn1(2, test),
fn2(1, test),
fn1(0.5, test),
fn3(0.2, test),
fn1(0.05, test),
]);
t.is(test.str, '10.20.050.52');
/** tag queue: concurrency 100 test */
test = { str: '' };
d4c = new D4C([{ concurrency: { limit: 100, tag: '2' } }]);
fn1 = d4c.wrap(timeout, { tag: '2' });
fn2 = d4c.wrap(immediateFun, { tag: '2' });
fn3 = d4c.wrap(immediateFunPromise, { tag: '2' });
yield Promise.all([
fn1(2, test),
fn2(1, test),
fn1(0.5, test),
fn3(0.2, test),
fn1(0.05, test),
]);
t.is(test.str, '10.20.050.52');
/** default queue: use setConcurrency to change concurrency on default to 100 */
test = { str: '' };
d4c = new D4C();
d4c.setConcurrency([{ limit: 100 }]);
fn1 = d4c.wrap(timeout);
fn2 = d4c.wrap(immediateFun);
fn3 = d4c.wrap(immediateFunPromise);
yield Promise.all([
fn1(2, test),
fn2(1, test),
fn1(0.5, test),
fn3(0.2, test),
fn1(0.05, test),
]);
t.is(test.str, '10.20.050.52');
/** new tag with setConcurrency to set concurrency 1 */
test = { str: '' };
d4c.setConcurrency([{ limit: 1, tag: '2' }]);
fn1 = d4c.wrap(timeout, { tag: '2' });
fn2 = d4c.wrap(immediateFun, { tag: '2' });
fn3 = d4c.wrap(immediateFunPromise, { tag: '2' });
yield Promise.all([
fn1(2, test),
fn2(1, test),
fn1(0.5, test),
fn3(0.2, test),
fn1(0.05, test),
]);
t.is(test.str, '210.50.20.05');
/** default queue: use setConcurrency to set it back to 1 */
test = { str: '' };
d4c.setConcurrency([{ limit: 1 }]);
fn1 = d4c.wrap(timeout);
fn2 = d4c.wrap(immediateFun);
fn3 = d4c.wrap(immediateFunPromise);
yield Promise.all([
fn1(2, test),
fn2(1, test),
fn1(0.5, test),
fn3(0.2, test),
fn1(0.05, test),
]);
t.is(test.str, '210.50.20.05');
let error = null;
try {
d4c.setConcurrency([undefined]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidQueueConcurrency);
error = null;
try {
d4c.setConcurrency([{ limit: -100 }]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidQueueConcurrency);
error = null;
try {
d4c.setConcurrency([{ tag: true, limit: 100 }]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidQueueTag);
error = null;
try {
d4c.setConcurrency([{ tag: true }]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidQueueConcurrency);
error = null;
try {
d4c.setConcurrency([{ tag: true, limit: '100' }]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidQueueConcurrency);
error = null;
try {
d4c = new D4C([{ concurrency: { limit: '11' } }]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidQueueConcurrency);
}));
test('Instance usage: pass a class arrow function property', (t) => __awaiter(void 0, void 0, void 0, function* () {
class TestController {
constructor(message) {
this.greet = (text) => __awaiter(this, void 0, void 0, function* () {
const str = 'Hello, ' + text + this.greeting;
return str;
});
this.greeting = message;
}
}
const d4c = new D4C();
const test = new TestController('!!');
const newFunc = d4c.wrap(test.greet, { tag: queueTag });
const job = newFunc(fixture2);
const resp = yield job;
t.is(resp, 'Hello, world!!');
/** wrap_exec part */
const resp2 = yield d4c.apply(test.greet, {
tag: queueTag,
args: [fixture2],
});
t.is(resp2, 'Hello, world!!');
}));
test('Decorator usage', (t) => __awaiter(void 0, void 0, void 0, function* () {
class TestController {
constructor(message) {
this.greeting = message;
this.testManualBind = this.testManualBind.bind(this);
}
greet(text) {
const str = 'Hello, ' + text + this.greeting;
return str;
}
testManualBind(text) {
return __awaiter(this, void 0, void 0, function* () {
const str = 'Hello, ' + text + this.greeting;
return str;
});
}
testAutoBind(text) {
return __awaiter(this, void 0, void 0, function* () {
const str = 'Hello, ' + text + this.greeting;
return str;
});
}
static staticMethod(text) {
return __awaiter(this, void 0, void 0, function* () {
return text;
});
}
static timeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
static timeoutAnotherQueue(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
instanceTimeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
instanceTimeoutError(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeoutError(seconds, obj);
});
}
testNoBlockCurr(seconds, obj) {
obj.str += seconds;
}
autobindMethodNoQueue(text) {
const str = 'Hello, ' + text + this.greeting;
return str;
}
}
__decorate([
synchronized
], TestController.prototype, "greet", null);
__decorate([
synchronized()
], TestController.prototype, "testManualBind", null);
__decorate([
autobind,
synchronized()
], TestController.prototype, "testAutoBind", null);
__decorate([
synchronized({ inheritPreErr: true })
], TestController.prototype, "instanceTimeout", null);
__decorate([
synchronized({})
], TestController.prototype, "instanceTimeoutError", null);
__decorate([
synchronized({ noBlockCurr: true })
], TestController.prototype, "testNoBlockCurr", null);
__decorate([
autobind
], TestController.prototype, "autobindMethodNoQueue", null);
__decorate([
synchronized({})
], TestController, "staticMethod", null);
__decorate([
synchronized
], TestController, "timeout", null);
__decorate([
synchronized({ tag: '2' })
], TestController, "timeoutAnotherQueue", null);
// /** instance method */
const testController = new TestController('!!');
t.is(yield testController.greet(fixture2), 'Hello, world!!');
/** test if this lib working with manual bind */
const testManualBind = testController.testManualBind;
t.is(yield testManualBind(fixture2), 'Hello, world!!');
/** test if this lib working with auto bind */
const testAutoBind = testController.testAutoBind;
t.is(yield testAutoBind(fixture2), 'Hello, world!!');
/** static method part */
t.is(yield TestController.staticMethod(fixture2), 'world');
/** Test if they are really executed one by one */
let test = { str: '' };
yield Promise.all([
TestController.timeout(0.5, test),
TestController.timeout(0.1, test),
]);
t.is(test.str, '0.50.1');
/** Test if these are really use different queues */
test = { str: '' };
yield Promise.all([
TestController.timeout(0.5, test),
TestController.timeoutAnotherQueue(0.1, test),
]);
t.is(test.str, '0.10.5');
//** Static and Instance method should have different queues */
test = { str: '' };
yield Promise.all([
TestController.timeout(0.5, test),
testController.instanceTimeout(0.1, test),
]);
t.is(test.str, '0.10.5');
//** Two instances should have different queues */
const testController2 = new TestController('!!');
test = { str: '' };
yield Promise.all([
testController2.instanceTimeout(0.5, test),
testController.instanceTimeout(0.1, test),
]);
t.is(test.str, '0.10.5');
/** Class instance and D4C instance should have different queues */
test = { str: '' };
const fn = new D4C().wrap(timeout);
yield Promise.all([fn(0.5, test), testController.instanceTimeout(0.1, test)]);
t.is(test.str, '0.10.5');
/** composite case: D4C instance on no autobind decorated method */
let error = null;
try {
const d4c = new D4C();
const newFunc = d4c.wrap(testController.greet);
const resp = yield newFunc('');
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.MissingThisDueBindIssue);
/** composite case: D4C instance on autobind decorated method */
const d4c = new D4C();
const result = yield d4c.apply(testController.testAutoBind, {
args: ['world'],
});
t.is(result, 'Hello, world!!');
/** composite case: D4C instance on autobind non-decorated method */
t.is(yield d4c.apply(testController.autobindMethodNoQueue), 'Hello, undefined!!');
/** Two class should not affect each other */
class TestController2 {
constructor(message) {
this.greeting = message;
}
static timeout(seconds, obj) {
return __awaiter(this, void 0, void 0, function* () {
yield timeout(seconds, obj);
});
}
}
__decorate([
synchronized({})
], TestController2, "timeout", null);
test = { str: '' };
yield Promise.all([
TestController.timeout(0.5, test),
TestController2.timeout(0.1, test),
]);
t.is(test.str, '0.10.5');
/** test invalid decorator */
error = null;
try {
class TestController4 {
static greet(text) {
return __awaiter(this, void 0, void 0, function* () {
return text;
});
}
}
__decorate([
synchronized({ tag: true })
], TestController4, "greet", null);
yield TestController4.greet(fixture2), 'world';
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InvalidDecoratorOption);
(() => __awaiter(void 0, void 0, void 0, function* () {
try {
yield testController.instanceTimeoutError(1, 'some_error');
}
catch (err) {
// console.log(" err by purpose")
}
}))();
error = null;
try {
yield testController.instanceTimeout(0.1, { str: '' });
}
catch (err) {
error = err;
}
t.is(error.message, 'some_error');
/** test if option noBlockCurr works on decorator */
test = { str: '' };
const job = testController.testNoBlockCurr(2, test);
test.str = test.str + '1';
yield job;
t.is(test.str, '12');
}));
test('Instance usage: funcAsync, symbol tag', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
const job = d4c.wrap(funcAsync, { tag: Symbol('123') })(fixture, fixture2);
t.is(yield job, 'helloworld');
}));
test('Instance usage: funcAsync, a invalid null tag case', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
let error;
try {
yield d4c.wrap(funcAsync, { tag: null });
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.InstanceInvalidTag);
}));
test('Instance usage: async function', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
const newFunc = d4c.wrap(funcAsync, { tag: queueTag });
const job = newFunc(fixture, fixture2);
const resp = yield job;
t.is(resp, 'helloworld');
}));
test('Instance usage: non-async function', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
const newFunc = d4c.wrap(funcSync, { tag: queueTag });
const job = newFunc(fixture, fixture2);
const resp = yield job;
t.is(resp, 'helloworld');
}));
test('Instance usage: promise-returning function', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
const job = d4c.wrap(funcPromise, { tag: queueTag })(fixture, fixture2);
const resp = yield job;
t.is(resp, 'helloworld');
}));
test('Instance usage: apply a funcAsync', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
/** apply */
const resp = yield d4c.apply(funcAsync, {
tag: queueTag,
args: [['33', '44'], '5'],
});
t.is(resp, '335');
}));
test('Instance usage: test if queue really work, execute one by one', (t) => __awaiter(void 0, void 0, void 0, function* () {
let test = { str: '' };
yield Promise.all([
timeout(2, test),
immediateFun(1, test),
timeout(0.5, test),
immediateFunPromise(0.2, test),
timeout(0.05, test),
]);
t.is(test.str, '10.20.050.52'); // 1, 0.2, 0.05, 0.5, 2
test = { str: '' };
const d4c = new D4C();
const fn1 = d4c.wrap(timeout);
const fn2 = d4c.wrap(immediateFun);
const fn3 = d4c.wrap(immediateFunPromise);
yield Promise.all([
fn1(2, test),
fn2(1, test),
fn1(0.5, test),
fn3(0.2, test),
fn1(0.05, test),
]);
t.is(test.str, '210.50.20.05');
test = { str: '' };
const d4c2 = new D4C();
const fn11 = d4c2.wrap(timeout, { tag: '1' });
const fn21 = d4c2.wrap(immediateFun, { tag: '2' });
const fn31 = d4c2.wrap(immediateFunPromise, { tag: '3' });
yield Promise.all([
fn11(2, test),
fn21(1, test),
fn11(0.5, test),
fn31(0.2, test),
fn11(0.05, test),
]);
t.is(test.str, '10.220.50.05'); // 1, 0.2, 2, 0.5, 0.05
test = { str: '' };
const fn12 = new D4C().wrap(timeout);
const fn22 = new D4C().wrap(immediateFun);
const fn32 = new D4C().wrap(immediateFunPromise);
yield Promise.all([
fn12(2, test),
fn22(1, test),
fn12(0.5, test),
fn32(0.2, test),
fn12(0.05, test),
]);
t.is(test.str, '10.220.50.05');
}));
test('Instance usage: option noBlockCurr enable, with two non-async function ', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
let testStr = '';
testStr += '1';
const newFunc = d4c.wrap(() => {
testStr += 'inFuncSyn';
}, { tag: queueTag, noBlockCurr: true });
testStr += '2';
const job = newFunc();
testStr += '3';
const newFunc2 = d4c.wrap(() => {
testStr += 'inFuncSyn2';
}, { tag: queueTag });
yield Promise.all([job, newFunc2()]);
testStr += '4';
t.is(testStr, '123inFuncSyninFuncSyn24');
}));
test("Instance usage: option inheritPreErr enable: task2 inherit task1's error in object queue", (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C();
const fun2 = () => __awaiter(void 0, void 0, void 0, function* () {
console.log('dummy fun2');
});
const fun1ErrorProducer = () => __awaiter(void 0, void 0, void 0, function* () {
try {
yield d4c.wrap(timeoutError)(1, new Error('some_error'));
}
catch (_) {
// console.log(" err by purpose")
}
});
fun1ErrorProducer();
let error;
try {
yield d4c.wrap(fun2, { inheritPreErr: true })();
}
catch (err) {
error = err;
}
t.is(error.message, 'some_error');
}));
test('Instance usage: test option dropWhenReachLimit', (t) => __awaiter(void 0, void 0, void 0, function* () {
const d4c = new D4C([{ concurrency: { limit: 2 } }]);
const fn1 = d4c.wrap(timeout, { dropWhenReachLimit: true });
let error = null;
try {
yield fn1(3);
yield Promise.all([fn1(3), fn1(3), fn1(3)]);
}
catch (err) {
error = err;
}
t.is(error.message, ErrMsg.QueueIsFull);
}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRDRDLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL0Q0Qy5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sUUFBUSxNQUFNLG9CQUFvQixDQUFBO0FBQ3pDLE9BQU8sSUFBSSxNQUFNLEtBQUssQ0FBQTtBQUV0QixPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUUzRSxNQUFNLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ3pCLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQTtBQUN4QixNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUE7QUFFekIsTUFBTSxTQUFTLEdBQUcsQ0FDaEIsS0FBZ0IsRUFDaEIsTUFBZSxFQUNFLEVBQUU7SUFDbkIsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFBO0FBQzFCLENBQUMsQ0FBQSxDQUFBO0FBRUQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxLQUFlLEVBQUUsTUFBYyxFQUFVLEVBQUU7SUFDM0QsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFBO0FBQzFCLENBQUMsQ0FBQTtBQUVELE1BQU0sV0FBVyxHQUFHLENBQUMsS0FBZSxFQUFFLE1BQWMsRUFBbUIsRUFBRTtJQUN2RSxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFBO0FBQzNDLENBQUMsQ0FBQTtBQUVELE1BQU0sT0FBTyxHQUFHLENBQUMsT0FBZSxFQUFFLE1BQXdCLEVBQUUsRUFBRTtJQUM1RCxPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQ3RDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxJQUFJLENBQUEsTUFB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