mirror of
https://github.com/wekan/wekan.git
synced 2025-12-19 17:00:13 +01:00
Fixed Non-ASCII attachment filename will crash when downloading.
Thanks to xet7 ! Fixes #2759
This commit is contained in:
parent
843ff8eaaa
commit
c2da477735
277 changed files with 30568 additions and 52 deletions
18
packages/wekan-cfs-power-queue/.editorconfig
Normal file
18
packages/wekan-cfs-power-queue/.editorconfig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# .editorconfig
|
||||
# Meteor adapted EditorConfig, http://EditorConfig.org
|
||||
# By RaiX 2013
|
||||
|
||||
root = true
|
||||
|
||||
[*.js]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
max_line_length = 80
|
||||
indent_brace_style = 1TBS
|
||||
spaces_around_operators = true
|
||||
quote_type = auto
|
||||
# curly_bracket_next_line = true
|
||||
3
packages/wekan-cfs-power-queue/.gitignore
vendored
Normal file
3
packages/wekan-cfs-power-queue/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/versions.json
|
||||
/nbproject/private/
|
||||
.build*
|
||||
114
packages/wekan-cfs-power-queue/.jshintrc
Normal file
114
packages/wekan-cfs-power-queue/.jshintrc
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
//.jshintrc
|
||||
{
|
||||
// JSHint Meteor Configuration File
|
||||
// Match the Meteor Style Guide
|
||||
//
|
||||
// By @raix with contributions from @aldeed and @awatson1978
|
||||
// Source https://github.com/raix/Meteor-jshintrc
|
||||
//
|
||||
// See http://jshint.com/docs/ for more details
|
||||
|
||||
"maxerr" : 50, // {int} Maximum error before stopping
|
||||
|
||||
// Enforcing
|
||||
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
|
||||
"camelcase" : true, // true: Identifiers must be in camelCase
|
||||
"curly" : true, // true: Require {} for every new block or scope
|
||||
"eqeqeq" : true, // true: Require triple equals (===) for comparison
|
||||
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
|
||||
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
|
||||
"indent" : 2, // {int} Number of spaces to use for indentation
|
||||
"latedef" : false, // true: Require variables/functions to be defined before being used
|
||||
"newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
|
||||
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
|
||||
"noempty" : true, // true: Prohibit use of empty blocks
|
||||
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
|
||||
"plusplus" : false, // true: Prohibit use of `++` & `--`
|
||||
"quotmark" : false, // Quotation mark consistency:
|
||||
// false : do nothing (default)
|
||||
// true : ensure whatever is used is consistent
|
||||
// "single" : require single quotes
|
||||
// "double" : require double quotes
|
||||
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
|
||||
"unused" : true, // true: Require all defined variables be used
|
||||
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
|
||||
"trailing" : true, // true: Prohibit trailing whitespaces
|
||||
"maxparams" : false, // {int} Max number of formal params allowed per function
|
||||
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
|
||||
"maxstatements" : false, // {int} Max number statements per function
|
||||
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
|
||||
"maxlen" : 80, // {int} Max number of characters per line
|
||||
|
||||
// Relaxing
|
||||
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
|
||||
"boss" : false, // true: Tolerate assignments where comparisons would be expected
|
||||
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
|
||||
"eqnull" : false, // true: Tolerate use of `== null`
|
||||
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
|
||||
"esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
|
||||
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
|
||||
// (ex: `for each`, multiple try/catch, function expression…)
|
||||
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
|
||||
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
|
||||
"funcscope" : false, // true: Tolerate defining variables inside control statements"
|
||||
"globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
|
||||
"iterator" : false, // true: Tolerate using the `__iterator__` property
|
||||
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
|
||||
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
|
||||
"laxcomma" : false, // true: Tolerate comma-first style coding
|
||||
"loopfunc" : false, // true: Tolerate functions being defined in loops
|
||||
"multistr" : false, // true: Tolerate multi-line strings
|
||||
"proto" : false, // true: Tolerate using the `__proto__` property
|
||||
"scripturl" : false, // true: Tolerate script-targeted URLs
|
||||
"smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
|
||||
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
|
||||
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
|
||||
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
|
||||
"validthis" : false, // true: Tolerate using this in a non-constructor function
|
||||
|
||||
// Environments
|
||||
"browser" : true, // Web Browser (window, document, etc)
|
||||
"couch" : false, // CouchDB
|
||||
"devel" : true, // Development/debugging (alert, confirm, etc)
|
||||
"dojo" : false, // Dojo Toolkit
|
||||
"jquery" : false, // jQuery
|
||||
"mootools" : false, // MooTools
|
||||
"node" : false, // Node.js
|
||||
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
|
||||
"prototypejs" : false, // Prototype and Scriptaculous
|
||||
"rhino" : false, // Rhino
|
||||
"worker" : false, // Web Workers
|
||||
"wsh" : false, // Windows Scripting Host
|
||||
"yui" : false, // Yahoo User Interface
|
||||
//"meteor" : false, // Meteor.js
|
||||
|
||||
// Legacy
|
||||
"nomen" : false, // true: Prohibit dangling `_` in variables
|
||||
"onevar" : false, // true: Allow only one `var` statement per function
|
||||
"passfail" : false, // true: Stop on first error
|
||||
"white" : false, // true: Check against strict whitespace and indentation rules
|
||||
|
||||
// Custom Globals
|
||||
"predef" : [
|
||||
"Meteor",
|
||||
"Accounts",
|
||||
"Session",
|
||||
"Template",
|
||||
"check",
|
||||
"Match",
|
||||
"Deps",
|
||||
"EJSON",
|
||||
"Email",
|
||||
"Package",
|
||||
"Tinytest",
|
||||
"Npm",
|
||||
"Assets",
|
||||
"Packages",
|
||||
"process",
|
||||
"GroundDB",
|
||||
"_gDB",
|
||||
"LocalCollection",
|
||||
"_",
|
||||
"Random"
|
||||
] // additional predefined global variables
|
||||
}
|
||||
5
packages/wekan-cfs-power-queue/.travis.yml
Normal file
5
packages/wekan-cfs-power-queue/.travis.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
before_install:
|
||||
- "curl -L http://git.io/s0Zu-w | /bin/sh"
|
||||
20
packages/wekan-cfs-power-queue/LICENSE.md
Normal file
20
packages/wekan-cfs-power-queue/LICENSE.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 [@raix](https://github.com/raix), aka Morten N.O. Nørgaard Henriksen, mh@gi-software.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
136
packages/wekan-cfs-power-queue/README.md
Normal file
136
packages/wekan-cfs-power-queue/README.md
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
wekan-cfs-power-queue [](https://travis-ci.org/CollectionFS/Meteor-powerqueue)
|
||||
=========
|
||||
|
||||
~~Looking for maintainers - please reach out!~~
|
||||
This package is to be archived due to inability to find contributors, thanks to everyone who helped make it possible.
|
||||
|
||||
**If you're looking for an alternative, we highly recommend [Meteor-Files](https://github.com/VeliovGroup/Meteor-Files) by [VeliovGroup](https://github.com/VeliovGroup)**
|
||||
|
||||
---
|
||||
|
||||
PowerQueue is a native Meteor package for memory-backed job queue processing. Features include:
|
||||
* async tasks
|
||||
* throttling resource usage
|
||||
* retrying failed tasks
|
||||
* managing sub-queues
|
||||
* powered by Meteor's reactive sugar
|
||||
* etc.
|
||||
|
||||
PowerQueue can use one of two [spinal-queue](https://github.com/zcfs/Meteor-power-queue/blob/master/spinal-queue.spec.md) packages, [ReactiveList](https://github.com/zcfs/Meteor-reactive-list) or [MicroQueue](https://github.com/zcfs/Meteor-micro-queue).
|
||||
|
||||
## Demos
|
||||
|
||||
**Check out the cool [live queue demo](http://power-queue-test.meteor.com) and [live sub queue example](http://power-queue-sub-test.meteor.com).**
|
||||
|
||||
Source code for both can be found in the two branches of the [power-queue-example repo](https://github.com/zcfs/power-queue-example).
|
||||
|
||||
|
||||
Kind regards,
|
||||
Eric(@aldeed) and Morten(@raix)
|
||||
|
||||
Happy coding!
|
||||
|
||||
# API
|
||||
All getters and setters are reactive.
|
||||
|
||||
[API Documentation](api.md)
|
||||
|
||||
## Helpers / Getters / Setters:
|
||||
* PowerQueue.length - Number of tasks in queue
|
||||
* PowerQueue.progress - Current progress in percent
|
||||
* PowerQueue.usage - Current load in percent
|
||||
* PowerQueue.total - Sum of tasks to run in current queue
|
||||
* PowerQueue.isPaused - True if queue is paused
|
||||
* PowerQueue.isHalted - True if queue is paused or stopped
|
||||
* PowerQueue.processing - Number of tasks being processed
|
||||
* PowerQueue.errors - Failures where task is passed to the errorHandler
|
||||
* PowerQueue.failures - Number of failures in current queue
|
||||
* PowerQueue.isRunning - True if queue is active
|
||||
* PowerQueue.maxProcessing - Getter + Setter for max tasks to run in parallel
|
||||
* PowerQueue.autostart - Getter + Setter for autostart flag - Allow add task to start the queue
|
||||
* PowerQueue.maxFailures - Max allowed retries for failing tasks before marked as an error
|
||||
* options.queue - Use custom micro-queue compatible queue
|
||||
* options.onEnded - Called when queue has ended
|
||||
* options.onRelease(remainingTasks) - Called when queue has ended or paused
|
||||
* options.onAutostart - Called when queue was autostarted
|
||||
|
||||
## Methods
|
||||
* PowerQueue.add(data) - Add a task to queue
|
||||
* PowerQueue.run() - Start the queue
|
||||
* PowerQueue.pause() - Pause the queue
|
||||
* PowerQueue.resume() - Resume the queue if paused
|
||||
* PowerQueue.reset() - Reset the queue
|
||||
* PowerQueue.taskHandler(data, next, failures) - Default task handler, where data is a `function(done)`, can be overwritten
|
||||
* PowerQueue.errorHandler(data, addTask, failures) - Default error handler, can be overwritten
|
||||
|
||||
# Example 1
|
||||
```js
|
||||
var queue = new PowerQueue({
|
||||
isPaused: true
|
||||
});
|
||||
|
||||
queue.add(function(done) {
|
||||
console.log('task 1');
|
||||
done();
|
||||
});
|
||||
queue.add(function(done) {
|
||||
console.log('task 2');
|
||||
done();
|
||||
});
|
||||
queue.add(function(done) {
|
||||
console.log('task 3');
|
||||
done();
|
||||
});
|
||||
|
||||
console.log('Ready to run queue');
|
||||
queue.run();
|
||||
```
|
||||
|
||||
# Example 2
|
||||
|
||||
This is a very rough example of how to make custom task handling.
|
||||
|
||||
```js
|
||||
|
||||
queue.errorHandler = function(data, addTask) {
|
||||
// This error handler lets the task drop, but we could use addTask to
|
||||
// Put the task into the queue again
|
||||
tasks.update({ _id: data.id }, { $set: { status: 'error'} });
|
||||
};
|
||||
|
||||
queue.taskHandler = function(data, next) {
|
||||
|
||||
// The task is now processed...
|
||||
tasks.update({ _id: data.id }, { $set: { status: 'processing'} });
|
||||
|
||||
Meteor.setTimeout(function() {
|
||||
if (Math.random() > 0.5) {
|
||||
// We random fail the task
|
||||
tasks.update({ _id: data.id }, { $set: { status: 'failed'} });
|
||||
// Returning error to next
|
||||
next('Error: Fail task');
|
||||
} else {
|
||||
// We are done!
|
||||
tasks.update({ _id: data.id }, { $set: { status: 'done'} });
|
||||
// Trigger next task
|
||||
next();
|
||||
}
|
||||
// This async task duration is between 500 - 1000ms
|
||||
}, Math.round(500 + 500 * Math.random()));
|
||||
};
|
||||
|
||||
// Add the task:
|
||||
var taskId = 0;
|
||||
queue.add({ id: tasks.insert({ status: 'added', index: ++taskId }) });
|
||||
```
|
||||
|
||||
# Contribute
|
||||
|
||||
Here's the [complete API documentation](internal.api.md), including private methods.
|
||||
|
||||
To update the docs, run `npm install docmeteor` then `docmeteor`.
|
||||
|
||||
|
||||
## TODO / Wishlist
|
||||
|
||||
* scheduling jobs to run in the future, like [meteor-queue](https://github.com/artwells/meteor-queue#features) - see [issue #15](https://github.com/zcfs/Meteor-power-queue/issues/15)
|
||||
420
packages/wekan-cfs-power-queue/api.md
Normal file
420
packages/wekan-cfs-power-queue/api.md
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
|
||||
#### <a name="PowerQueue"></a>new PowerQueue([options]) <sub><i>Anywhere</i></sub> ####
|
||||
```
|
||||
Creates an instance of a power queue
|
||||
[Check out demo](http://power-queue-test.meteor.com/)
|
||||
```
|
||||
-
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __options__ *{object}* (Optional)
|
||||
Settings
|
||||
- __filo__ *{boolean}* (Default = false)
|
||||
Make it a first in last out queue
|
||||
- __isPaused__ *{boolean}* (Default = false)
|
||||
Set queue paused
|
||||
- __autostart__ *{boolean}* (Default = true)
|
||||
May adding a task start the queue
|
||||
- __name__ *{string}* (Default = "Queue")
|
||||
Name of the queue
|
||||
- __maxProcessing__ *{number}* (Default = 1)
|
||||
Limit of simultanous running tasks
|
||||
- __maxFailures__ *{number}* (Default = 5)
|
||||
Limit retries of failed tasks, if 0 or below we allow infinite failures
|
||||
- __jumpOnFailure__ *{number}* (Default = true)
|
||||
Jump to next task and retry failed task later
|
||||
- __debug__ *{boolean}* (Default = false)
|
||||
Log verbose messages to the console
|
||||
- __reactive__ *{boolean}* (Default = true)
|
||||
Set whether or not this queue should be reactive
|
||||
- __spinalQueue__ *{[SpinalQueue](spinal-queue.spec.md)}* (Optional)
|
||||
Set spinal queue uses pr. default `MicroQueue` or `ReactiveList` if added to the project
|
||||
|
||||
-
|
||||
|
||||
|
||||
|
||||
> ```PowerQueue = function(options) { ...``` [power-queue.js:27](power-queue.js#L27)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.onEnded"></a>*powerqueue*.onEnded <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __onEnded__ is defined in `PowerQueue`*
|
||||
Is called when queue is ended
|
||||
|
||||
> ```self.onEnded = options && options.onEnded || function() { ...``` [power-queue.js:103](power-queue.js#L103)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.onRelease"></a>*powerqueue*.onRelease <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __onRelease__ is defined in `PowerQueue`*
|
||||
Is called when queue is released
|
||||
|
||||
> ```self.onRelease = options && options.onRelease || function() { ...``` [power-queue.js:110](power-queue.js#L110)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.onAutostart"></a>*powerqueue*.onAutostart <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __onAutostart__ is defined in `PowerQueue`*
|
||||
Is called when queue is auto started
|
||||
|
||||
> ```self.onAutostart = options && options.onAutostart || function() { ...``` [power-queue.js:115](power-queue.js#L115)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.total"></a>*powerqueue*.total() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __total__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The total number of tasks added to this queue
|
||||
|
||||
> ```self.total = self._maxLength.get;``` [power-queue.js:123](power-queue.js#L123)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.isPaused"></a>*powerqueue*.isPaused() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __isPaused__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
Status of the paused state of the queue
|
||||
|
||||
> ```self.isPaused = self._paused.get;``` [power-queue.js:129](power-queue.js#L129)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.processing"></a>*powerqueue*.processing() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __processing__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Number of tasks currently being processed
|
||||
|
||||
> ```self.processing = self._isProcessing.get;``` [power-queue.js:135](power-queue.js#L135)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.errors"></a>*powerqueue*.errors() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __errors__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The total number of errors
|
||||
Errors are triggered when [maxFailures](PowerQueue.maxFailures) are exeeded
|
||||
|
||||
> ```self.errors = self._errors.get;``` [power-queue.js:142](power-queue.js#L142)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.failures"></a>*powerqueue*.failures() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __failures__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The total number of failed tasks
|
||||
|
||||
> ```self.failures = self._failures.get;``` [power-queue.js:148](power-queue.js#L148)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.isRunning"></a>*powerqueue*.isRunning() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __isRunning__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
True if the queue is running
|
||||
> NOTE: The task can be paused but marked as running
|
||||
|
||||
> ```self.isRunning = self._running.get;``` [power-queue.js:155](power-queue.js#L155)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.maxProcessing"></a>*powerqueue*.maxProcessing([max]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __maxProcessing__ is defined in `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __max__ *{number}* (Optional)
|
||||
If not used this function works as a getter
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Maximum number of simultaneous processing tasks
|
||||
|
||||
Example:
|
||||
```js
|
||||
foo.maxProcessing(); // Works as a getter and returns the current value
|
||||
foo.maxProcessing(20); // This sets the value to 20
|
||||
```
|
||||
|
||||
> ```self.maxProcessing = self._maxProcessing.getset;``` [power-queue.js:168](power-queue.js#L168)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.autostart"></a>*powerqueue*.autostart([autorun]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __autostart__ is defined in `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __autorun__ *{boolean}* (Optional)
|
||||
If not used this function works as a getter
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
If adding a task may trigger the queue to start
|
||||
|
||||
Example:
|
||||
```js
|
||||
foo.autostart(); // Works as a getter and returns the current value
|
||||
foo.autostart(true); // This sets the value to true
|
||||
```
|
||||
|
||||
> ```self.autostart = self._autostart.getset;``` [power-queue.js:189](power-queue.js#L189)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.maxFailures"></a>*powerqueue*.maxFailures([max]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __maxFailures__ is defined in `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __max__ *{number}* (Optional)
|
||||
If not used this function works as a getter
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The maximum for failures pr. task before triggering an error
|
||||
|
||||
Example:
|
||||
```js
|
||||
foo.maxFailures(); // Works as a getter and returns the current value
|
||||
foo.maxFailures(10); // This sets the value to 10
|
||||
```
|
||||
|
||||
> ```self.maxFailures = self._maxFailures.getset;``` [power-queue.js:202](power-queue.js#L202)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.processList"></a>*powerqueue*.processList() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __processList__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{array}* __(is reactive)__
|
||||
List of tasks currently being processed
|
||||
|
||||
> ```PowerQueue.prototype.processingList = function() { ...``` [power-queue.js:209](power-queue.js#L209)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.isHalted"></a>*powerqueue*.isHalted() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __isHalted__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
True if the queue is not running or paused
|
||||
|
||||
> ```PowerQueue.prototype.isHalted = function() { ...``` [power-queue.js:218](power-queue.js#L218)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.length"></a>*powerqueue*.length() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __length__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Number of tasks left in queue to be processed
|
||||
|
||||
> ```PowerQueue.prototype.length = function() { ...``` [power-queue.js:227](power-queue.js#L227)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.progress"></a>*powerqueue*.progress() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __progress__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
0 .. 100 % Indicates the status of the queue
|
||||
|
||||
> ```PowerQueue.prototype.progress = function() { ...``` [power-queue.js:236](power-queue.js#L236)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.usage"></a>*powerqueue*.usage() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __usage__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
0 .. 100 % Indicates ressource usage of the queue
|
||||
|
||||
> ```PowerQueue.prototype.usage = function() { ...``` [power-queue.js:249](power-queue.js#L249)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.reset"></a>*powerqueue*.reset() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __reset__ is defined in `prototype` of `PowerQueue`*
|
||||
Calling this will:
|
||||
* stop the queue
|
||||
* paused to false
|
||||
* Discart all queue data
|
||||
|
||||
> NOTE: At the moment if the queue has processing tasks they can change
|
||||
> the `errors` and `failures` counters. This could change in the future or
|
||||
> be prevented by creating a whole new instance of the `PowerQueue`
|
||||
|
||||
> ```PowerQueue.prototype.reset = function() { ...``` [power-queue.js:264](power-queue.js#L264)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.add"></a>*powerqueue*.add(data, [failures]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __add__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __data__ *{any}*
|
||||
The task to be handled
|
||||
* __failures__ *{number}* (Optional)
|
||||
Internally used to Pass on number of failures.
|
||||
|
||||
-
|
||||
|
||||
> ```PowerQueue.prototype.add = function(data, failures, id) { ...``` [power-queue.js:316](power-queue.js#L316)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.next"></a>*powerqueue*.next([err]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __next__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __err__ *{string}* (Optional)
|
||||
Error message if task failed
|
||||
|
||||
-
|
||||
> * Can pass in `null` to start the queue
|
||||
> * Passing in a string to `next` will trigger a failure
|
||||
> * Passing nothing will simply let the next task run
|
||||
`next` is handed into the [taskHandler](PowerQueue.taskHandler) as a
|
||||
callback to mark an error or end of current task
|
||||
|
||||
> ```PowerQueue.prototype.next = function(err) { ...``` [power-queue.js:394](power-queue.js#L394)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.queueTaskHandler"></a>*powerqueue*.queueTaskHandler() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __queueTaskHandler__ is defined in `prototype` of `PowerQueue`*
|
||||
This method handles tasks that are sub queues
|
||||
|
||||
> ```PowerQueue.prototype.queueTaskHandler = function(subQueue, next, failures) { ...``` [power-queue.js:555](power-queue.js#L555)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.taskHandler"></a>*powerqueue*.taskHandler <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __taskHandler__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __data__ *{any}*
|
||||
This can be data or functions
|
||||
* __next__ *{function}*
|
||||
Function `next` call this to end task
|
||||
* __failures__ *{number}*
|
||||
Number of failures on this task
|
||||
|
||||
-
|
||||
|
||||
Default task handler expects functions as data:
|
||||
```js
|
||||
self.taskHandler = function(data, next, failures) {
|
||||
// This default task handler expects invocation to be a function to run
|
||||
if (typeof data !== 'function') {
|
||||
throw new Error('Default task handler expects a function');
|
||||
}
|
||||
try {
|
||||
// Have the function call next
|
||||
data(next, failures);
|
||||
} catch(err) {
|
||||
// Throw to fail this task
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
> ```PowerQueue.prototype.taskHandler = function(data, next, failures) { ...``` [power-queue.js:601](power-queue.js#L601)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.errorHandler"></a>*powerqueue*.errorHandler <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __errorHandler__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __data__ *{any}*
|
||||
This can be data or functions
|
||||
* __addTask__ *{function}*
|
||||
Use this function to insert the data into the queue again
|
||||
* __failures__ *{number}*
|
||||
Number of failures on this task
|
||||
|
||||
-
|
||||
|
||||
The default callback:
|
||||
```js
|
||||
var foo = new PowerQueue();
|
||||
|
||||
// Overwrite the default action
|
||||
foo.errorHandler = function(data, addTask, failures) {
|
||||
// This could be overwritten the data contains the task data and addTask
|
||||
// is a helper for adding the task to the queue
|
||||
// try again: addTask(data);
|
||||
// console.log('Terminate at ' + failures + ' failures');
|
||||
};
|
||||
```
|
||||
|
||||
> ```PowerQueue.prototype.errorHandler = function(data, addTask, failures) { ...``` [power-queue.js:634](power-queue.js#L634)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.pause"></a>*powerqueue*.pause() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __pause__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
> ```PowerQueue.prototype.pause = function() { ...``` [power-queue.js:645](power-queue.js#L645)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.resume"></a>*powerqueue*.resume() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __resume__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
> This will not start a stopped queue
|
||||
|
||||
> ```PowerQueue.prototype.resume = function() { ...``` [power-queue.js:665](power-queue.js#L665)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.run"></a>*powerqueue*.run() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __run__ is defined in `prototype` of `PowerQueue`*
|
||||
> Using this command will resume a paused queue and will
|
||||
> start a stopped queue.
|
||||
|
||||
> ```PowerQueue.prototype.run = function() { ...``` [power-queue.js:677](power-queue.js#L677)
|
||||
|
||||
-
|
||||
535
packages/wekan-cfs-power-queue/internal.api.md
Normal file
535
packages/wekan-cfs-power-queue/internal.api.md
Normal file
|
|
@ -0,0 +1,535 @@
|
|||
> File: ["power-queue.js"](power-queue.js)
|
||||
> Where: {client|server}
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue"></a>new PowerQueue([options]) <sub><i>Anywhere</i></sub> ####
|
||||
```
|
||||
Creates an instance of a power queue
|
||||
[Check out demo](http://power-queue-test.meteor.com/)
|
||||
```
|
||||
-
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __options__ *{object}* (Optional)
|
||||
Settings
|
||||
- __filo__ *{boolean}* (Default = false)
|
||||
Make it a first in last out queue
|
||||
- __isPaused__ *{boolean}* (Default = false)
|
||||
Set queue paused
|
||||
- __autostart__ *{boolean}* (Default = true)
|
||||
May adding a task start the queue
|
||||
- __name__ *{string}* (Default = "Queue")
|
||||
Name of the queue
|
||||
- __maxProcessing__ *{number}* (Default = 1)
|
||||
Limit of simultanous running tasks
|
||||
- __maxFailures__ *{number}* (Default = 5)
|
||||
Limit retries of failed tasks, if 0 or below we allow infinite failures
|
||||
- __jumpOnFailure__ *{number}* (Default = true)
|
||||
Jump to next task and retry failed task later
|
||||
- __debug__ *{boolean}* (Default = false)
|
||||
Log verbose messages to the console
|
||||
- __reactive__ *{boolean}* (Default = true)
|
||||
Set whether or not this queue should be reactive
|
||||
- __spinalQueue__ *{[SpinalQueue](spinal-queue.spec.md)}* (Optional)
|
||||
Set spinal queue uses pr. default `MicroQueue` or `ReactiveList` if added to the project
|
||||
|
||||
-
|
||||
|
||||
|
||||
|
||||
> ```PowerQueue = function(options) { ...``` [power-queue.js:27](power-queue.js#L27)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.onEnded"></a>*powerqueue*.onEnded <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __onEnded__ is defined in `PowerQueue`*
|
||||
Is called when queue is ended
|
||||
|
||||
> ```self.onEnded = options && options.onEnded || function() { ...``` [power-queue.js:103](power-queue.js#L103)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.onRelease"></a>*powerqueue*.onRelease <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __onRelease__ is defined in `PowerQueue`*
|
||||
Is called when queue is released
|
||||
|
||||
> ```self.onRelease = options && options.onRelease || function() { ...``` [power-queue.js:110](power-queue.js#L110)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.onAutostart"></a>*powerqueue*.onAutostart <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __onAutostart__ is defined in `PowerQueue`*
|
||||
Is called when queue is auto started
|
||||
|
||||
> ```self.onAutostart = options && options.onAutostart || function() { ...``` [power-queue.js:115](power-queue.js#L115)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.total"></a>*powerqueue*.total() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __total__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The total number of tasks added to this queue
|
||||
|
||||
> ```self.total = self._maxLength.get;``` [power-queue.js:123](power-queue.js#L123)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.isPaused"></a>*powerqueue*.isPaused() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __isPaused__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
Status of the paused state of the queue
|
||||
|
||||
> ```self.isPaused = self._paused.get;``` [power-queue.js:129](power-queue.js#L129)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.processing"></a>*powerqueue*.processing() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __processing__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Number of tasks currently being processed
|
||||
|
||||
> ```self.processing = self._isProcessing.get;``` [power-queue.js:135](power-queue.js#L135)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.errors"></a>*powerqueue*.errors() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __errors__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The total number of errors
|
||||
Errors are triggered when [maxFailures](PowerQueue.maxFailures) are exeeded
|
||||
|
||||
> ```self.errors = self._errors.get;``` [power-queue.js:142](power-queue.js#L142)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.failures"></a>*powerqueue*.failures() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __failures__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The total number of failed tasks
|
||||
|
||||
> ```self.failures = self._failures.get;``` [power-queue.js:148](power-queue.js#L148)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.isRunning"></a>*powerqueue*.isRunning() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __isRunning__ is defined in `PowerQueue`*
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
True if the queue is running
|
||||
> NOTE: The task can be paused but marked as running
|
||||
|
||||
> ```self.isRunning = self._running.get;``` [power-queue.js:155](power-queue.js#L155)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.maxProcessing"></a>*powerqueue*.maxProcessing([max]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __maxProcessing__ is defined in `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __max__ *{number}* (Optional)
|
||||
If not used this function works as a getter
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Maximum number of simultaneous processing tasks
|
||||
|
||||
Example:
|
||||
```js
|
||||
foo.maxProcessing(); // Works as a getter and returns the current value
|
||||
foo.maxProcessing(20); // This sets the value to 20
|
||||
```
|
||||
|
||||
> ```self.maxProcessing = self._maxProcessing.getset;``` [power-queue.js:168](power-queue.js#L168)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.autostart"></a>*powerqueue*.autostart([autorun]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __autostart__ is defined in `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __autorun__ *{boolean}* (Optional)
|
||||
If not used this function works as a getter
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
If adding a task may trigger the queue to start
|
||||
|
||||
Example:
|
||||
```js
|
||||
foo.autostart(); // Works as a getter and returns the current value
|
||||
foo.autostart(true); // This sets the value to true
|
||||
```
|
||||
|
||||
> ```self.autostart = self._autostart.getset;``` [power-queue.js:189](power-queue.js#L189)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.maxFailures"></a>*powerqueue*.maxFailures([max]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __maxFailures__ is defined in `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __max__ *{number}* (Optional)
|
||||
If not used this function works as a getter
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
The maximum for failures pr. task before triggering an error
|
||||
|
||||
Example:
|
||||
```js
|
||||
foo.maxFailures(); // Works as a getter and returns the current value
|
||||
foo.maxFailures(10); // This sets the value to 10
|
||||
```
|
||||
|
||||
> ```self.maxFailures = self._maxFailures.getset;``` [power-queue.js:202](power-queue.js#L202)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.processList"></a>*powerqueue*.processList() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __processList__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{array}* __(is reactive)__
|
||||
List of tasks currently being processed
|
||||
|
||||
> ```PowerQueue.prototype.processingList = function() { ...``` [power-queue.js:209](power-queue.js#L209)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.isHalted"></a>*powerqueue*.isHalted() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __isHalted__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{boolean}* __(is reactive)__
|
||||
True if the queue is not running or paused
|
||||
|
||||
> ```PowerQueue.prototype.isHalted = function() { ...``` [power-queue.js:218](power-queue.js#L218)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.length"></a>*powerqueue*.length() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __length__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Number of tasks left in queue to be processed
|
||||
|
||||
> ```PowerQueue.prototype.length = function() { ...``` [power-queue.js:227](power-queue.js#L227)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.progress"></a>*powerqueue*.progress() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __progress__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
0 .. 100 % Indicates the status of the queue
|
||||
|
||||
> ```PowerQueue.prototype.progress = function() { ...``` [power-queue.js:236](power-queue.js#L236)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.usage"></a>*powerqueue*.usage() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __usage__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
0 .. 100 % Indicates ressource usage of the queue
|
||||
|
||||
> ```PowerQueue.prototype.usage = function() { ...``` [power-queue.js:249](power-queue.js#L249)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.reset"></a>*powerqueue*.reset() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __reset__ is defined in `prototype` of `PowerQueue`*
|
||||
Calling this will:
|
||||
* stop the queue
|
||||
* paused to false
|
||||
* Discart all queue data
|
||||
|
||||
> NOTE: At the moment if the queue has processing tasks they can change
|
||||
> the `errors` and `failures` counters. This could change in the future or
|
||||
> be prevented by creating a whole new instance of the `PowerQueue`
|
||||
|
||||
> ```PowerQueue.prototype.reset = function() { ...``` [power-queue.js:264](power-queue.js#L264)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue._autoStartTasks"></a>*powerqueue*._autoStartTasks() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method is private*
|
||||
*This method ___autoStartTasks__ is defined in `PowerQueue`*
|
||||
|
||||
This method defines the autostart algorithm that allows add task to trigger
|
||||
a start of the queue if queue is not paused.
|
||||
|
||||
> ```PowerQueue.prototype._autoStartTasks = function() { ...``` [power-queue.js:289](power-queue.js#L289)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.add"></a>*powerqueue*.add(data, [failures]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __add__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __data__ *{any}*
|
||||
The task to be handled
|
||||
* __failures__ *{number}* (Optional)
|
||||
Internally used to Pass on number of failures.
|
||||
|
||||
-
|
||||
|
||||
> ```PowerQueue.prototype.add = function(data, failures, id) { ...``` [power-queue.js:316](power-queue.js#L316)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.updateThrottleUp"></a>*powerqueue*.updateThrottleUp() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method is private*
|
||||
*This method __updateThrottleUp__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
Calling this method will update the throttle on the queue adding tasks.
|
||||
|
||||
> Note: Currently we only support the PowerQueue - but we could support
|
||||
> a more general interface for pauseable tasks or other usecases.
|
||||
|
||||
> ```PowerQueue.prototype.updateThrottleUp = function() { ...``` [power-queue.js:342](power-queue.js#L342)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.updateThrottleDown"></a>*powerqueue*.updateThrottleDown() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method is private*
|
||||
*This method __updateThrottleDown__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
Calling this method will update the throttle on the queue pause tasks.
|
||||
|
||||
> Note: Currently we only support the PowerQueue - but we could support
|
||||
> a more general interface for pauseable tasks or other usecases.
|
||||
|
||||
> ```PowerQueue.prototype.updateThrottleDown = function() { ...``` [power-queue.js:367](power-queue.js#L367)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.next"></a>*powerqueue*.next([err]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __next__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __err__ *{string}* (Optional)
|
||||
Error message if task failed
|
||||
|
||||
-
|
||||
> * Can pass in `null` to start the queue
|
||||
> * Passing in a string to `next` will trigger a failure
|
||||
> * Passing nothing will simply let the next task run
|
||||
`next` is handed into the [taskHandler](PowerQueue.taskHandler) as a
|
||||
callback to mark an error or end of current task
|
||||
|
||||
> ```PowerQueue.prototype.next = function(err) { ...``` [power-queue.js:394](power-queue.js#L394)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="done"></a>done <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __feedback__ *{[Meteor.Error ](#Meteor.Error )|[ Error ](# Error )|[ String ](# String )|[ null](# null)}* (Optional)
|
||||
This allows the task to communicate with the queue
|
||||
|
||||
-
|
||||
|
||||
Explaination of `feedback`
|
||||
* `Meteor.Error` This means that the task failed in a controlled manner and is allowed to rerun
|
||||
* `Error` This will throw the passed error - as its an unitended error
|
||||
* `null` The task is not done yet, rerun later
|
||||
* `String` The task can perform certain commands on the queue
|
||||
* "pause" - pause the queue
|
||||
* "stop" - stop the queue
|
||||
* "reset" - reset the queue
|
||||
* "cancel" - cancel the queue
|
||||
|
||||
|
||||
> ```PowerQueue.prototype.runTaskDone = function(feedback, invocation) { ...``` [power-queue.js:452](power-queue.js#L452)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.runTaskDone"></a>*powerqueue*.runTaskDone([feedback], invocation) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method is private*
|
||||
*This method __runTaskDone__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __feedback__ *{[Meteor.Error ](#Meteor.Error )|[ Error ](# Error )|[ String ](# String )|[ null](# null)}* (Optional)
|
||||
This allows the task to communicate with the queue
|
||||
* __invocation__ *{object}*
|
||||
|
||||
-
|
||||
|
||||
> Note: `feedback` is explained in [Done callback](#done)
|
||||
|
||||
|
||||
> ```PowerQueue.prototype.runTaskDone = function(feedback, invocation) { ...``` [power-queue.js:452](power-queue.js#L452)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.runTask"></a>*powerqueue*.runTask(invocation) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method is private*
|
||||
*This method __runTask__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __invocation__ *{object}*
|
||||
The object stored in the micro-queue
|
||||
|
||||
-
|
||||
|
||||
> ```PowerQueue.prototype.runTask = function(invocation) { ...``` [power-queue.js:521](power-queue.js#L521)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.queueTaskHandler"></a>*powerqueue*.queueTaskHandler() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __queueTaskHandler__ is defined in `prototype` of `PowerQueue`*
|
||||
This method handles tasks that are sub queues
|
||||
|
||||
> ```PowerQueue.prototype.queueTaskHandler = function(subQueue, next, failures) { ...``` [power-queue.js:555](power-queue.js#L555)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.taskHandler"></a>*powerqueue*.taskHandler <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __taskHandler__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __data__ *{any}*
|
||||
This can be data or functions
|
||||
* __next__ *{function}*
|
||||
Function `next` call this to end task
|
||||
* __failures__ *{number}*
|
||||
Number of failures on this task
|
||||
|
||||
-
|
||||
|
||||
Default task handler expects functions as data:
|
||||
```js
|
||||
self.taskHandler = function(data, next, failures) {
|
||||
// This default task handler expects invocation to be a function to run
|
||||
if (typeof data !== 'function') {
|
||||
throw new Error('Default task handler expects a function');
|
||||
}
|
||||
try {
|
||||
// Have the function call next
|
||||
data(next, failures);
|
||||
} catch(err) {
|
||||
// Throw to fail this task
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
> ```PowerQueue.prototype.taskHandler = function(data, next, failures) { ...``` [power-queue.js:601](power-queue.js#L601)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.errorHandler"></a>*powerqueue*.errorHandler <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This callback __errorHandler__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __data__ *{any}*
|
||||
This can be data or functions
|
||||
* __addTask__ *{function}*
|
||||
Use this function to insert the data into the queue again
|
||||
* __failures__ *{number}*
|
||||
Number of failures on this task
|
||||
|
||||
-
|
||||
|
||||
The default callback:
|
||||
```js
|
||||
var foo = new PowerQueue();
|
||||
|
||||
// Overwrite the default action
|
||||
foo.errorHandler = function(data, addTask, failures) {
|
||||
// This could be overwritten the data contains the task data and addTask
|
||||
// is a helper for adding the task to the queue
|
||||
// try again: addTask(data);
|
||||
// console.log('Terminate at ' + failures + ' failures');
|
||||
};
|
||||
```
|
||||
|
||||
> ```PowerQueue.prototype.errorHandler = function(data, addTask, failures) { ...``` [power-queue.js:634](power-queue.js#L634)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.pause"></a>*powerqueue*.pause() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __pause__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__TODO__
|
||||
```
|
||||
* We should have it pause all processing tasks
|
||||
```
|
||||
|
||||
> ```PowerQueue.prototype.pause = function() { ...``` [power-queue.js:645](power-queue.js#L645)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.resume"></a>*powerqueue*.resume() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __resume__ is defined in `prototype` of `PowerQueue`*
|
||||
|
||||
__TODO__
|
||||
```
|
||||
* We should have it resume all processing tasks
|
||||
```
|
||||
|
||||
> This will not start a stopped queue
|
||||
|
||||
> ```PowerQueue.prototype.resume = function() { ...``` [power-queue.js:665](power-queue.js#L665)
|
||||
|
||||
-
|
||||
|
||||
#### <a name="PowerQueue.prototype.run"></a>*powerqueue*.run() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __run__ is defined in `prototype` of `PowerQueue`*
|
||||
> Using this command will resume a paused queue and will
|
||||
> start a stopped queue.
|
||||
|
||||
> ```PowerQueue.prototype.run = function() { ...``` [power-queue.js:677](power-queue.js#L677)
|
||||
|
||||
-
|
||||
27
packages/wekan-cfs-power-queue/package.js
Normal file
27
packages/wekan-cfs-power-queue/package.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Package.describe({
|
||||
name: 'wekan-cfs-power-queue',
|
||||
version: '0.9.11',
|
||||
summary: "PowerQueue is a powerful tool for handling async tasks, throtling etc.",
|
||||
git: 'https://github.com/zcfs/Meteor-power-queue.git'
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
api.versionsFrom('1.0');
|
||||
|
||||
api.use(['deps', 'wekan-cfs-reactive-property@0.0.4'], ['client', 'server']);
|
||||
|
||||
// We let the user decide what spinal queue to use - We support both
|
||||
// reactive-list and micro-queue they obey the spinal-queue spec
|
||||
api.use(['wekan-cfs-reactive-list@0.0.9', 'wekan-cfs-micro-queue@0.0.6'], ['client', 'server'], { weak: true });
|
||||
|
||||
api.export && api.export('PowerQueue');
|
||||
api.addFiles(['power-queue.js'], ['client', 'server']);
|
||||
});
|
||||
|
||||
Package.onTest(function (api) {
|
||||
api.use(['wekan-cfs-power-queue', 'wekan-cfs-reactive-list']);
|
||||
api.use('test-helpers', ['server', 'client']);
|
||||
api.use('tinytest');
|
||||
|
||||
api.addFiles('tests.js');
|
||||
});
|
||||
727
packages/wekan-cfs-power-queue/power-queue.js
Normal file
727
packages/wekan-cfs-power-queue/power-queue.js
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
// Rig weak dependencies
|
||||
if (typeof MicroQueue === 'undefined' && Package['micro-queue']) {
|
||||
MicroQueue = Package['micro-queue'].MicroQueue;
|
||||
}
|
||||
if (typeof ReactiveList === 'undefined' && Package['reactive-list']) {
|
||||
ReactiveList = Package['reactive-list'].ReactiveList;
|
||||
}
|
||||
|
||||
// Rig weak dependencies in +0.9.1
|
||||
if (typeof MicroQueue === 'undefined' && Package['wekan-cfs-micro-queue']) {
|
||||
MicroQueue = Package['wekan-cfs-micro-queue'].MicroQueue;
|
||||
}
|
||||
if (typeof ReactiveList === 'undefined' && Package['wekan-cfs-reactive-list']) {
|
||||
ReactiveList = Package['wekan-cfs-reactive-list'].ReactiveList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of a power queue // Testing inline comment
|
||||
* [Check out demo](http://power-queue-test.meteor.com/)
|
||||
*
|
||||
* @constructor
|
||||
* @self powerqueue
|
||||
* @param {object} [options] Settings
|
||||
* @param {boolean} [options.filo=false] Make it a first in last out queue
|
||||
* @param {boolean} [options.isPaused=false] Set queue paused
|
||||
* @param {boolean} [options.autostart=true] May adding a task start the queue
|
||||
* @param {string} [options.name="Queue"] Name of the queue
|
||||
* @param {number} [options.maxProcessing=1] Limit of simultanous running tasks
|
||||
* @param {number} [options.maxFailures = 5] Limit retries of failed tasks, if 0 or below we allow infinite failures
|
||||
* @param {number} [options.jumpOnFailure = true] Jump to next task and retry failed task later
|
||||
* @param {boolean} [options.debug=false] Log verbose messages to the console
|
||||
* @param {boolean} [options.reactive=true] Set whether or not this queue should be reactive
|
||||
* @param {boolean} [options.onAutostart] Callback for the queue autostart event
|
||||
* @param {boolean} [options.onPaused] Callback for the queue paused event
|
||||
* @param {boolean} [options.onReleased] Callback for the queue release event
|
||||
* @param {boolean} [options.onEnded] Callback for the queue end event
|
||||
* @param {[SpinalQueue](spinal-queue.spec.md)} [options.spinalQueue] Set spinal queue uses pr. default `MicroQueue` or `ReactiveList` if added to the project
|
||||
*/
|
||||
PowerQueue = function(options) {
|
||||
var self = this;
|
||||
var test = 5;
|
||||
|
||||
self.reactive = (options && options.reactive === false) ? false : true;
|
||||
|
||||
// Allow user to use another micro-queue #3
|
||||
// We try setting the ActiveQueue to MicroQueue if installed in the app
|
||||
var ActiveQueue = (typeof MicroQueue !== 'undefined') && MicroQueue || undefined;
|
||||
|
||||
// If ReactiveList is added to the project we use this over MicroQueue
|
||||
ActiveQueue = (typeof ReactiveList !== 'undefined') && ReactiveList || ActiveQueue;
|
||||
|
||||
// We allow user to overrule and set a custom spinal-queue spec complient queue
|
||||
if (options && typeof options.spinalQueue !== 'undefined') {
|
||||
ActiveQueue = options.spinalQueue;
|
||||
}
|
||||
|
||||
if (typeof ActiveQueue === 'undefined') {
|
||||
console.log('Error: You need to add a spinal queue to the project');
|
||||
console.log('Please add "micro-queue", "reactive-list" to the project');
|
||||
throw new Error('Please add "micro-queue", "reactive-list" or other spinalQueue compatible packages');
|
||||
}
|
||||
|
||||
// Default is fifo lilo
|
||||
self.invocations = new ActiveQueue({
|
||||
//
|
||||
sort: (options && (options.filo || options.lifo)),
|
||||
reactive: self.reactive
|
||||
});
|
||||
//var self.invocations = new ReactiveList(queueOrder);
|
||||
|
||||
// List of current tasks being processed
|
||||
self._processList = new ActiveQueue({
|
||||
reactive: self.reactive
|
||||
}); //ReactiveList();
|
||||
|
||||
// Max number of simultanious tasks being processed
|
||||
self._maxProcessing = new ReactiveProperty(options && options.maxProcessing || 1, self.reactive);
|
||||
|
||||
// Reactive number of tasks being processed
|
||||
self._isProcessing = new ReactiveProperty(0, self.reactive);
|
||||
|
||||
// Boolean indicating if queue is paused or not
|
||||
self._paused = new ReactiveProperty((options && options.isPaused || false), self.reactive);
|
||||
|
||||
// Boolean indicator for queue status active / running (can still be paused)
|
||||
self._running = new ReactiveProperty(false, self.reactive);
|
||||
|
||||
// Counter for errors, errors are triggered if maxFailures is exeeded
|
||||
self._errors = new ReactiveProperty(0, self.reactive);
|
||||
|
||||
// Counter for task failures, contains error count
|
||||
self._failures = new ReactiveProperty(0, self.reactive);
|
||||
|
||||
// On failure jump to new task - if false the current task is rerun until error
|
||||
self._jumpOnFailure = (options && options.jumpOnFailure === false) ? false : true;
|
||||
|
||||
// Count of all added tasks
|
||||
self._maxLength = new ReactiveProperty(0, self.reactive);
|
||||
|
||||
// Boolean indicate whether or not a "add" task is allowed to start the queue
|
||||
self._autostart = new ReactiveProperty( ((options && options.autostart === false) ? false : true), self.reactive);
|
||||
|
||||
// Limit times a task is allowed to fail and be rerun later before triggering an error
|
||||
self._maxFailures = new ReactiveProperty( (options && options.maxFailures || 5), self.reactive);
|
||||
|
||||
// Name / title of this queue - Not used - should deprecate
|
||||
self.title = options && options.name || 'Queue';
|
||||
|
||||
// debug - will print error / failures passed to next
|
||||
self.debug = !!(options && options.debug);
|
||||
|
||||
/** @method PowerQueue.total
|
||||
* @reactive
|
||||
* @returns {number} The total number of tasks added to this queue
|
||||
*/
|
||||
self.total = self._maxLength.get;
|
||||
|
||||
/** @method PowerQueue.isPaused
|
||||
* @reactive
|
||||
* @returns {boolean} Status of the paused state of the queue
|
||||
*/
|
||||
self.isPaused = self._paused.get;
|
||||
|
||||
/** @method PowerQueue.processing
|
||||
* @reactive
|
||||
* @returns {number} Number of tasks currently being processed
|
||||
*/
|
||||
self.processing = self._isProcessing.get;
|
||||
|
||||
/** @method PowerQueue.errors
|
||||
* @reactive
|
||||
* @returns {number} The total number of errors
|
||||
* Errors are triggered when [maxFailures](PowerQueue.maxFailures) are exeeded
|
||||
*/
|
||||
self.errors = self._errors.get;
|
||||
|
||||
/** @method PowerQueue.failures
|
||||
* @reactive
|
||||
* @returns {number} The total number of failed tasks
|
||||
*/
|
||||
self.failures = self._failures.get;
|
||||
|
||||
/** @method PowerQueue.isRunning
|
||||
* @reactive
|
||||
* @returns {boolean} True if the queue is running
|
||||
* > NOTE: The task can be paused but marked as running
|
||||
*/
|
||||
self.isRunning = self._running.get;
|
||||
|
||||
/** @method PowerQueue.maxProcessing Get setter for maxProcessing
|
||||
* @param {number} [max] If not used this function works as a getter
|
||||
* @reactive
|
||||
* @returns {number} Maximum number of simultaneous processing tasks
|
||||
*
|
||||
* Example:
|
||||
* ```js
|
||||
* foo.maxProcessing(); // Works as a getter and returns the current value
|
||||
* foo.maxProcessing(20); // This sets the value to 20
|
||||
* ```
|
||||
*/
|
||||
self.maxProcessing = self._maxProcessing.getset;
|
||||
|
||||
self._maxProcessing.onChange = function() {
|
||||
// The user can change the max allowed processing tasks up or down here...
|
||||
// Update the throttle up
|
||||
self.updateThrottleUp();
|
||||
// Update the throttle down
|
||||
self.updateThrottleDown();
|
||||
};
|
||||
|
||||
/** @method PowerQueue.autostart Get setter for autostart
|
||||
* @param {boolean} [autorun] If not used this function works as a getter
|
||||
* @reactive
|
||||
* @returns {boolean} If adding a task may trigger the queue to start
|
||||
*
|
||||
* Example:
|
||||
* ```js
|
||||
* foo.autostart(); // Works as a getter and returns the current value
|
||||
* foo.autostart(true); // This sets the value to true
|
||||
* ```
|
||||
*/
|
||||
self.autostart = self._autostart.getset;
|
||||
|
||||
/** @method PowerQueue.maxFailures Get setter for maxFailures
|
||||
* @param {number} [max] If not used this function works as a getter
|
||||
* @reactive
|
||||
* @returns {number} The maximum for failures pr. task before triggering an error
|
||||
*
|
||||
* Example:
|
||||
* ```js
|
||||
* foo.maxFailures(); // Works as a getter and returns the current value
|
||||
* foo.maxFailures(10); // This sets the value to 10
|
||||
* ```
|
||||
*/
|
||||
self.maxFailures = self._maxFailures.getset;
|
||||
|
||||
/** @callback PowerQueue.onPaused
|
||||
* Is called when queue is ended
|
||||
*/
|
||||
self.onPaused = options && options.onPaused || function() {
|
||||
self.debug && console.log(self.title + ' ENDED');
|
||||
};
|
||||
|
||||
/** @callback PowerQueue.onEnded
|
||||
* Is called when queue is ended
|
||||
*/
|
||||
self.onEnded = options && options.onEnded || function() {
|
||||
self.debug && console.log(self.title + ' ENDED');
|
||||
};
|
||||
|
||||
/** @callback PowerQueue.onRelease
|
||||
* Is called when queue is released
|
||||
*/
|
||||
self.onRelease = options && options.onRelease || function() {
|
||||
self.debug && console.log(self.title + ' RELEASED');
|
||||
};
|
||||
|
||||
/** @callback PowerQueue.onAutostart
|
||||
* Is called when queue is auto started
|
||||
*/
|
||||
self.onAutostart = options && options.onAutostart || function() {
|
||||
self.debug && console.log(self.title + ' Autostart');
|
||||
};
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.processList
|
||||
* @reactive
|
||||
* @returns {array} List of tasks currently being processed
|
||||
*/
|
||||
PowerQueue.prototype.processingList = function() {
|
||||
var self = this;
|
||||
return self._processList.fetch();
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.isHalted
|
||||
* @reactive
|
||||
* @returns {boolean} True if the queue is not running or paused
|
||||
*/
|
||||
PowerQueue.prototype.isHalted = function() {
|
||||
var self = this;
|
||||
return (!self._running.get() || self._paused.get());
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.length
|
||||
* @reactive
|
||||
* @returns {number} Number of tasks left in queue to be processed
|
||||
*/
|
||||
PowerQueue.prototype.length = function() {
|
||||
var self = this;
|
||||
return self.invocations.length();
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.progress
|
||||
* @reactive
|
||||
* @returns {number} 0 .. 100 % Indicates the status of the queue
|
||||
*/
|
||||
PowerQueue.prototype.progress = function() {
|
||||
var self = this;
|
||||
var progress = self._maxLength.get() - self.invocations.length() - self._isProcessing.get();
|
||||
if (self._maxLength.value > 0) {
|
||||
return Math.round(progress / self._maxLength.value * 100);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.usage
|
||||
* @reactive
|
||||
* @returns {number} 0 .. 100 % Indicates resource usage of the queue
|
||||
*/
|
||||
PowerQueue.prototype.usage = function() {
|
||||
var self = this;
|
||||
return Math.round(self._isProcessing.get() / self._maxProcessing.get() * 100);
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.reset Reset the queue
|
||||
* Calling this will:
|
||||
* * stop the queue
|
||||
* * paused to false
|
||||
* * Discart all queue data
|
||||
*
|
||||
* > NOTE: At the moment if the queue has processing tasks they can change
|
||||
* > the `errors` and `failures` counters. This could change in the future or
|
||||
* > be prevented by creating a whole new instance of the `PowerQueue`
|
||||
*/
|
||||
PowerQueue.prototype.reset = function() {
|
||||
var self = this;
|
||||
self.debug && console.log(self.title + ' RESET');
|
||||
self._running.set(false);
|
||||
self._paused.set(false);
|
||||
self.invocations.reset();
|
||||
self._processList.reset();
|
||||
|
||||
// // Loop through the processing tasks and reset these
|
||||
// self._processList.forEach(function(data) {
|
||||
// if (data.queue instanceof PowerQueue) {
|
||||
// data.queue.reset();
|
||||
// }
|
||||
// }, true);
|
||||
self._maxLength.set(0);
|
||||
self._failures.set(0);
|
||||
self._errors.set(0);
|
||||
};
|
||||
|
||||
/** @method PowerQueue._autoStartTasks
|
||||
* @private
|
||||
*
|
||||
* This method defines the autostart algorithm that allows add task to trigger
|
||||
* a start of the queue if queue is not paused.
|
||||
*/
|
||||
PowerQueue.prototype._autoStartTasks = function() {
|
||||
var self = this;
|
||||
|
||||
// We dont start anything by ourselfs if queue is paused
|
||||
if (!self._paused.value) {
|
||||
|
||||
// Queue is not running and we are set to autostart so we start the queue
|
||||
if (!self._running.value && self._autostart.value) {
|
||||
// Trigger callback / event
|
||||
self.onAutostart();
|
||||
// Set queue as running
|
||||
self._running.set(true);
|
||||
}
|
||||
|
||||
// Make sure that we use all available resources
|
||||
if (self._running.value) {
|
||||
// Call next to start up the queue
|
||||
self.next(null);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.add
|
||||
* @param {any} data The task to be handled
|
||||
* @param {number} [failures] Used internally to Pass on number of failures.
|
||||
*/
|
||||
PowerQueue.prototype.add = function(data, failures, id) {
|
||||
var self = this;
|
||||
|
||||
// Assign new id to task
|
||||
var assignNewId = self._jumpOnFailure || typeof id === 'undefined';
|
||||
|
||||
// Set the task id
|
||||
var taskId = (assignNewId) ? self._maxLength.value + 1 : id;
|
||||
|
||||
// self.invocations.add({ _id: currentId, data: data, failures: failures || 0 }, reversed);
|
||||
self.invocations.insert(taskId, { _id: taskId, data: data, failures: failures || 0 });
|
||||
|
||||
// If we assigned new id then increase length
|
||||
if (assignNewId) self._maxLength.inc();
|
||||
|
||||
self._autoStartTasks();
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.updateThrottleUp
|
||||
* @private
|
||||
*
|
||||
* Calling this method will update the throttle on the queue adding tasks.
|
||||
*
|
||||
* > Note: Currently we only support the PowerQueue - but we could support
|
||||
* > a more general interface for pauseable tasks or other usecases.
|
||||
*/
|
||||
PowerQueue.prototype.updateThrottleUp = function() {
|
||||
var self = this;
|
||||
|
||||
// How many additional tasks can we handle?
|
||||
var availableSlots = self._maxProcessing.value - self._isProcessing.value;
|
||||
// If we can handle more, we have more, we're running, and we're not paused
|
||||
if (!self._paused.value && self._running.value && availableSlots > 0 && self.invocations._length > 0) {
|
||||
// Increase counter of current number of tasks being processed
|
||||
self._isProcessing.inc();
|
||||
// Run task
|
||||
self.runTask(self.invocations.getFirstItem());
|
||||
// Repeat recursively; this is better than a for loop to avoid blocking the UI
|
||||
self.updateThrottleUp();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.updateThrottleDown
|
||||
* @private
|
||||
*
|
||||
* Calling this method will update the throttle on the queue pause tasks.
|
||||
*
|
||||
* > Note: Currently we only support the PowerQueue - but we could support
|
||||
* > a more general interface for pauseable tasks or other usecases.
|
||||
*/
|
||||
PowerQueue.prototype.updateThrottleDown = function() {
|
||||
var self = this;
|
||||
// Calculate the differece between acutuall processing tasks and target
|
||||
var diff = self._isProcessing.value - self._maxProcessing.value;
|
||||
|
||||
// If the diff is more than 0 then we have many tasks processing.
|
||||
if (diff > 0) {
|
||||
// We pause the latest added tasks
|
||||
self._processList.forEachReverse(function(data) {
|
||||
if (diff > 0 && data.queue instanceof PowerQueue) {
|
||||
diff--;
|
||||
// We dont mind calling pause on multiple times on each task
|
||||
// theres a simple check going on preventing any duplicate actions
|
||||
data.queue.pause();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.next
|
||||
* @param {string} [err] Error message if task failed
|
||||
* > * Can pass in `null` to start the queue
|
||||
* > * Passing in a string to `next` will trigger a failure
|
||||
* > * Passing nothing will simply let the next task run
|
||||
* `next` is handed into the [taskHandler](PowerQueue.taskHandler) as a
|
||||
* callback to mark an error or end of current task
|
||||
*/
|
||||
PowerQueue.prototype.next = function(err) {
|
||||
var self = this;
|
||||
// Primary concern is to throttle up because we are either:
|
||||
// 1. Starting the queue
|
||||
// 2. Starting next task
|
||||
//
|
||||
// This function does not shut down running tasks
|
||||
self.updateThrottleUp();
|
||||
|
||||
// We are running, no tasks are being processed even we just updated the
|
||||
// throttle up and we got no errors.
|
||||
// 1. We are paused and releasing tasks
|
||||
// 2. We are done
|
||||
if (self._running.value && self._isProcessing.value === 0 && err !== null) {
|
||||
|
||||
// We have no tasks processing so this queue is now releasing resources
|
||||
// this could be that the queue is paused or stopped, in that case the
|
||||
// self.invocations._length would be > 0
|
||||
// If on the other hand the self.invocations._length is 0 then we have no more
|
||||
// tasks in the queue so the queue has ended
|
||||
self.onRelease(self.invocations._length);
|
||||
|
||||
if (!self.invocations._length) { // !self._paused.value &&
|
||||
// Check if queue is done working
|
||||
// Stop the queue
|
||||
self._running.set(false);
|
||||
// self.invocations.reset(); // This should be implicit
|
||||
self.onEnded();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/** @callback done
|
||||
* @param {Meteor.Error | Error | String | null} [feedback] This allows the task to communicate with the queue
|
||||
*
|
||||
* Explaination of `feedback`
|
||||
* * `Meteor.Error` This means that the task failed in a controlled manner and is allowed to rerun
|
||||
* * `Error` This will throw the passed error - as its an unitended error
|
||||
* * `null` The task is not done yet, rerun later
|
||||
* * `String` The task can perform certain commands on the queue
|
||||
* * "pause" - pause the queue
|
||||
* * "stop" - stop the queue
|
||||
* * "reset" - reset the queue
|
||||
* * "cancel" - cancel the queue
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** @method PowerQueue.prototype.runTaskDone
|
||||
* @private
|
||||
* @param {Meteor.Error | Error | String | null} [feedback] This allows the task to communicate with the queue
|
||||
* @param {object} invocation
|
||||
*
|
||||
* > Note: `feedback` is explained in [Done callback](#done)
|
||||
*
|
||||
*/
|
||||
// Rig the callback function
|
||||
PowerQueue.prototype.runTaskDone = function(feedback, invocation) {
|
||||
var self = this;
|
||||
|
||||
// If the task handler throws an error then add it to the queue again
|
||||
// we allow this for a max of self._maxFailures
|
||||
// If the error is null then we add the task silently back into the
|
||||
// microQueue in reverse... This could be due to pause or throttling
|
||||
if (feedback instanceof Meteor.Error) {
|
||||
// We only count failures if maxFailures are above 0
|
||||
if (self._maxFailures.value > 0) invocation.failures++;
|
||||
self._failures.inc();
|
||||
|
||||
// If the user has set the debug flag we print out failures/errors
|
||||
self.debug && console.error('Error: "' + self.title + '" ' + feedback.message + ', ' + feedback.stack);
|
||||
|
||||
if (invocation.failures < self._maxFailures.value) {
|
||||
// Add the task again with the increased failures
|
||||
self.add(invocation.data, invocation.failures, invocation._id);
|
||||
} else {
|
||||
self._errors.inc();
|
||||
self.errorHandler(invocation.data, self.add, invocation.failures);
|
||||
}
|
||||
|
||||
// If a error is thrown we assume its not intended
|
||||
} else if (feedback instanceof Error) throw feedback;
|
||||
|
||||
if (feedback)
|
||||
|
||||
// We use null to throttle pauseable tasks
|
||||
if (feedback === null) {
|
||||
// We add this task into the queue, no questions asked
|
||||
self.invocations.insert(invocation._id, { data: invocation.data, failures: invocation.failures, _id: invocation._id });
|
||||
}
|
||||
|
||||
// If the user returns a string we got a command
|
||||
if (feedback === ''+feedback) {
|
||||
var command = {
|
||||
'pause': function() { self.pause(); },
|
||||
'stop': function() { self.stop(); },
|
||||
'reset': function() { self.reset(); },
|
||||
'cancel': function() { self.cancel(); },
|
||||
};
|
||||
if (typeof command[feedback] === 'function') {
|
||||
// Run the command on this queue
|
||||
command[feedback]();
|
||||
} else {
|
||||
// We dont recognize this command, throw an error
|
||||
throw new Error('Unknown queue command "' + feedback + '"');
|
||||
}
|
||||
}
|
||||
// Decrease the number of tasks being processed
|
||||
// make sure we dont go below 0
|
||||
if (self._isProcessing.value > 0) self._isProcessing.dec();
|
||||
// Task has ended we remove the task from the process list
|
||||
self._processList.remove(invocation._id);
|
||||
|
||||
invocation.data = null;
|
||||
invocation.failures = null;
|
||||
invocation._id = null;
|
||||
invocation = null;
|
||||
delete invocation;
|
||||
// Next task
|
||||
Meteor.setTimeout(function() {
|
||||
self.next();
|
||||
}, 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** @method PowerQueue.prototype.runTask
|
||||
* @private // This is not part of the open api
|
||||
* @param {object} invocation The object stored in the micro-queue
|
||||
*/
|
||||
PowerQueue.prototype.runTask = function(invocation) {
|
||||
var self = this;
|
||||
|
||||
// We start the fitting task handler
|
||||
// Currently we only support the PowerQueue but we could have a more general
|
||||
// interface for tasks that allow throttling
|
||||
try {
|
||||
if (invocation.data instanceof PowerQueue) {
|
||||
|
||||
// Insert PowerQueue into process list
|
||||
self._processList.insert(invocation._id, { id: invocation._id, queue: invocation.data });
|
||||
// Handle task
|
||||
self.queueTaskHandler(invocation.data, function subQueueCallbackDone(feedback) {
|
||||
self.runTaskDone(feedback, invocation);
|
||||
}, invocation.failures);
|
||||
|
||||
} else {
|
||||
|
||||
// Insert task into process list
|
||||
self._processList.insert(invocation._id, invocation.data);
|
||||
// Handle task
|
||||
self.taskHandler(invocation.data, function taskCallbackDone(feedback) {
|
||||
self.runTaskDone(feedback, invocation);
|
||||
}, invocation.failures);
|
||||
|
||||
}
|
||||
} catch(err) {
|
||||
throw new Error('Error while running taskHandler for queue, Error: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.queueTaskHandler
|
||||
* This method handles tasks that are sub queues
|
||||
*/
|
||||
PowerQueue.prototype.queueTaskHandler = function(subQueue, next, failures) {
|
||||
var self = this;
|
||||
// Monitor sub queue task releases
|
||||
subQueue.onRelease = function(remaining) {
|
||||
// Ok, we were paused - this could be throttling so we respect this
|
||||
// So when the queue is halted we add it back into the main queue
|
||||
if (remaining > 0) {
|
||||
// We get out of the queue but dont repport error and add to run later
|
||||
next(null);
|
||||
} else {
|
||||
// Queue has ended
|
||||
// We simply trigger next task when the sub queue is complete
|
||||
next();
|
||||
// When running subqueues it doesnt make sense to track failures and retry
|
||||
// the sub queue - this is sub queue domain
|
||||
}
|
||||
};
|
||||
|
||||
// Start the queue
|
||||
subQueue.run();
|
||||
};
|
||||
|
||||
/** @callback PowerQueue.prototype.taskHandler
|
||||
* @param {any} data This can be data or functions
|
||||
* @param {function} next Function `next` call this to end task
|
||||
* @param {number} failures Number of failures on this task
|
||||
*
|
||||
* Default task handler expects functions as data:
|
||||
* ```js
|
||||
* self.taskHandler = function(data, next, failures) {
|
||||
* // This default task handler expects invocation to be a function to run
|
||||
* if (typeof data !== 'function') {
|
||||
* throw new Error('Default task handler expects a function');
|
||||
* }
|
||||
* try {
|
||||
* // Have the function call next
|
||||
* data(next, failures);
|
||||
* } catch(err) {
|
||||
* // Throw to fail this task
|
||||
* next(err);
|
||||
* }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
|
||||
// Can be overwrittin by the user
|
||||
PowerQueue.prototype.taskHandler = function(data, next, failures) {
|
||||
var self = this;
|
||||
// This default task handler expects invocation to be a function to run
|
||||
if (typeof data !== 'function') {
|
||||
throw new Error('Default task handler expects a function');
|
||||
}
|
||||
try {
|
||||
// Have the function call next
|
||||
data(next, failures);
|
||||
} catch(err) {
|
||||
// Throw to fail this task
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
|
||||
/** @callback PowerQueue.prototype.errorHandler
|
||||
* @param {any} data This can be data or functions
|
||||
* @param {function} addTask Use this function to insert the data into the queue again
|
||||
* @param {number} failures Number of failures on this task
|
||||
*
|
||||
* The default callback:
|
||||
* ```js
|
||||
* var foo = new PowerQueue();
|
||||
*
|
||||
* // Overwrite the default action
|
||||
* foo.errorHandler = function(data, addTask, failures) {
|
||||
* // This could be overwritten the data contains the task data and addTask
|
||||
* // is a helper for adding the task to the queue
|
||||
* // try again: addTask(data);
|
||||
* // console.log('Terminate at ' + failures + ' failures');
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
PowerQueue.prototype.errorHandler = function(data, addTask, failures) {
|
||||
var self = this;
|
||||
// This could be overwritten the data contains the task data and addTask
|
||||
// is a helper for adding the task to the queue
|
||||
// try again: addTask(data);
|
||||
self.debug && console.log('Terminate at ' + failures + ' failures');
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.pause Pause the queue
|
||||
* @todo We should have it pause all processing tasks
|
||||
*/
|
||||
PowerQueue.prototype.pause = function() {
|
||||
var self = this;
|
||||
if (!self._paused.value) {
|
||||
|
||||
self._paused.set(true);
|
||||
// Loop through the processing tasks and pause these
|
||||
self._processList.forEach(function(data) {
|
||||
if (data.queue instanceof PowerQueue) {
|
||||
// Pause the sub queue
|
||||
data.queue.pause();
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Trigger callback
|
||||
self.onPaused();
|
||||
}
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.resume Start a paused queue
|
||||
* @todo We should have it resume all processing tasks
|
||||
*
|
||||
* > This will not start a stopped queue
|
||||
*/
|
||||
PowerQueue.prototype.resume = function() {
|
||||
var self = this;
|
||||
self.run();
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.run Starts the queue
|
||||
* > Using this command will resume a paused queue and will
|
||||
* > start a stopped queue.
|
||||
*/
|
||||
PowerQueue.prototype.run = function() {
|
||||
var self = this;
|
||||
//not paused and already running or queue empty or paused subqueues
|
||||
if (!self._paused.value && self._running.value || !self.invocations._length) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._paused.set(false);
|
||||
self._running.set(true);
|
||||
self.next(null);
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.stop Stops the queue
|
||||
*/
|
||||
PowerQueue.prototype.stop = function() {
|
||||
var self = this;
|
||||
self._running.set(false);
|
||||
};
|
||||
|
||||
/** @method PowerQueue.prototype.cancel Cancel the queue
|
||||
*/
|
||||
PowerQueue.prototype.cancel = function() {
|
||||
var self = this;
|
||||
self.reset();
|
||||
};
|
||||
|
||||
151
packages/wekan-cfs-power-queue/spinal-queue.spec.md
Normal file
151
packages/wekan-cfs-power-queue/spinal-queue.spec.md
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#Spinal Queue Spec
|
||||
This specification declares the interface for the "spinal" queue in `PowerQueue`.
|
||||
We allready have two implementations the [MicroQueue](https://github.com/zcfs/Meteor-micro-queue) and [ReactiveList](https://github.com/zcfs/Meteor-reactive-list)
|
||||
|
||||
#SpinalQueue
|
||||
Provides a simple reactive list interface
|
||||
|
||||
#### <a name="SpinalQueue"></a>new SpinalQueue(lifo) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __lifo__ *{boolean}*
|
||||
Set the order of the queue default is `fifo`
|
||||
|
||||
-
|
||||
Example:
|
||||
```js
|
||||
var list = new SpinalQueue();
|
||||
list.insert(1, { text: 'Hello id: 1' });
|
||||
list.insert(2, { text: 'Hello id: 2' });
|
||||
list.insert(3, { text: 'Hello id: 3' });
|
||||
list.update(2, { text: 'Updated 2'});
|
||||
list.remove(1);
|
||||
|
||||
list.forEach(function(value, key) {
|
||||
console.log('GOT: ' + value.text);
|
||||
}, true); // Set noneReactive = true, default behaviour is reactive
|
||||
// Return from Template:
|
||||
Template.hello.list = function() {
|
||||
return list.fetch();
|
||||
};
|
||||
```
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.length"></a>*SpinalQueue*.length() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __length__ is defined in `SpinalQueue`*
|
||||
|
||||
__Returns__ *{number}* __(is reactive)__
|
||||
Length of the reactive list
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.reset"></a>*SpinalQueue*.reset() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __reset__ is defined in `SpinalQueue`*
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.update"></a>*SpinalQueue*.update(key, value) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __update__ is defined in `SpinalQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __key__ *{string|number}*
|
||||
Key to update
|
||||
* __value__ *{any}*
|
||||
Update with this value
|
||||
|
||||
> Note: Method is currently not used by `PowerQueue`
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.insert"></a>*SpinalQueue*.insert(key, value) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __insert__ is defined in `SpinalQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __key__ *{string|number}*
|
||||
Key to insert
|
||||
* __value__ *{any}*
|
||||
Insert item with this value
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.remove"></a>*SpinalQueue*.remove(key) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __remove__ is defined in `SpinalQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __key__ *{string|number}*
|
||||
Key to remove
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.getLastItem"></a>*SpinalQueue*.getLastItem() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __getLastItem__ is defined in `SpinalQueue`*
|
||||
|
||||
__Returns__ *{any}*
|
||||
Pops last item from the list - removes the item from the list
|
||||
|
||||
> Note: Method is currently not used by `PowerQueue`
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.getFirstItem"></a>*SpinalQueue*.getFirstItem() <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __getFirstItem__ is defined in `SpinalQueue`*
|
||||
|
||||
__Returns__ *{any}*
|
||||
Pops first item from the list - removes the item from the list
|
||||
|
||||
|
||||
#### <a name="SpinalQueue.forEach"></a>*SpinalQueue*.forEach(f, [noneReactive], [reverse]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __forEach__ is defined in `SpinalQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __f__ *{function}*
|
||||
Callback `funciton(value, key)`
|
||||
* __noneReactive__ *{boolean}* (Optional = false)
|
||||
Set true if want to disable reactivity
|
||||
|
||||
-
|
||||
|
||||
|
||||
#### <a name="SpinalQueue.forEachReverse"></a>*SpinalQueue*.forEachReverse(f, [noneReactive]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __forEachReverse__ is defined in `SpinalQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __f__ *{function}*
|
||||
Callback `funciton(value, key)`
|
||||
* __noneReactive__ *{boolean}* (Optional = false)
|
||||
Set true if want to disable reactivity
|
||||
|
||||
-
|
||||
|
||||
#### <a name="SpinalQueue.fetch"></a>*SpinalQueue*.fetch([noneReactive]) <sub><i>Anywhere</i></sub> ####
|
||||
-
|
||||
*This method __fetch__ is defined in `SpinalQueue`*
|
||||
|
||||
__Arguments__
|
||||
|
||||
* __noneReactive__ *{boolean}* (Optional = false)
|
||||
Set true if want to disable reactivity
|
||||
|
||||
-
|
||||
|
||||
__Returns__ *{array}* __(is reactive)__
|
||||
List of items
|
||||
|
||||
-
|
||||
198
packages/wekan-cfs-power-queue/tests.js
Normal file
198
packages/wekan-cfs-power-queue/tests.js
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
"use strict";
|
||||
|
||||
function equals(a, b) {
|
||||
return !!(JSON.stringify(a) === JSON.stringify(b));
|
||||
}
|
||||
|
||||
Tinytest.add('PowerQueue - scope', function(test) {
|
||||
|
||||
test.isTrue(typeof PowerQueue !== 'undefined', 'The PowerQueue scope is missing, please add the power-queue package');
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
// We run 5 tasks in serial mode
|
||||
Tinytest.addAsync('PowerQueue - test serial run', function (test, onComplete) {
|
||||
var queue = new PowerQueue({
|
||||
name: 'test queue 1',
|
||||
autostart: false,
|
||||
maxProcessing: 1,
|
||||
debug: true,
|
||||
// When this task is released we do our tests
|
||||
onEnded: function() {
|
||||
console.log('It ended');
|
||||
// Check that we ran the expected number of tasks
|
||||
test.equal(counter, 5, 'counter did not match number of tasks');
|
||||
// Check that the result was correct
|
||||
test.equal(result, expectedResult, 'result was unexpected');
|
||||
// We are done testing
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
var result = '';
|
||||
var expectedResult = '12345';
|
||||
var counter = 0;
|
||||
|
||||
var checkCounter = function(id, next) {
|
||||
console.log('test queue 1 - Run task: ' + id);
|
||||
// Keep a counter
|
||||
counter++;
|
||||
// push id to result
|
||||
result += id;
|
||||
// call next task
|
||||
next();
|
||||
};
|
||||
|
||||
|
||||
// Add the tasks to the queue
|
||||
queue.add(function(next) { checkCounter('1', next); });
|
||||
queue.add(function(next) { checkCounter('2', next); });
|
||||
queue.add(function(next) { checkCounter('3', next); });
|
||||
queue.add(function(next) { checkCounter('4', next); });
|
||||
queue.add(function(next) { checkCounter('5', next); });
|
||||
|
||||
// Run the queue
|
||||
queue.run();
|
||||
});
|
||||
|
||||
// We run 5 tasks in serial mode but pause the queue on 3
|
||||
Tinytest.addAsync('PowerQueue - test serial pause', function (test, onComplete) {
|
||||
var queue = new PowerQueue({
|
||||
name: 'test queue 2',
|
||||
autostart: false,
|
||||
maxProcessing: 1,
|
||||
debug: true,
|
||||
// When this task is released we do our tests
|
||||
onPaused: function() {
|
||||
console.log('Its paused');
|
||||
// Check that we ran the expected number of tasks
|
||||
test.equal(counter, 3, 'counter did not match number of tasks');
|
||||
// Check that the result was correct
|
||||
test.equal(result, expectedResult, 'result was unexpected');
|
||||
// We are done testing
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
var result = '';
|
||||
var expectedResult = '123';
|
||||
var counter = 0;
|
||||
|
||||
var checkCounter = function(id, next) {
|
||||
console.log('test queue 2 - Run task: ' + id);
|
||||
// Keep a counter
|
||||
counter++;
|
||||
// push id to result
|
||||
result += id;
|
||||
// call next task
|
||||
if (id === '3')
|
||||
next('pause')
|
||||
else
|
||||
next();
|
||||
};
|
||||
|
||||
|
||||
// Add the tasks to the queue
|
||||
queue.add(function(next) { checkCounter('1', next); });
|
||||
queue.add(function(next) { checkCounter('2', next); });
|
||||
queue.add(function(next) { checkCounter('3', next); });
|
||||
queue.add(function(next) { checkCounter('4', next); });
|
||||
queue.add(function(next) { checkCounter('5', next); });
|
||||
|
||||
// Run the queue
|
||||
queue.run();
|
||||
});
|
||||
|
||||
// We run 5 tasks in serial mode but pause the queue on 3
|
||||
Tinytest.addAsync('PowerQueue - test 2 task in parallel', function (test, onComplete) {
|
||||
var queue = new PowerQueue({
|
||||
name: 'test queue 3',
|
||||
autostart: false,
|
||||
maxProcessing: 2,
|
||||
debug: true,
|
||||
// When this task is released we do our tests
|
||||
onEnded: function() {
|
||||
console.log('Its paused');
|
||||
// Check that we ran the expected number of tasks
|
||||
test.equal(counter, 10, 'counter did not match number of tasks');
|
||||
// Check that the result was correct
|
||||
test.equal(result, expectedResult, 'result was unexpected');
|
||||
// We are done testing
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
// start 1-----3-------4-------6------------------------9-----------------------X
|
||||
// 2-----------------5---------------7--------8-----------10------X
|
||||
// ms 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
|
||||
// result 1 2 3 4 5 6 7 8 9 10
|
||||
// result 1 3 2 4 5 7 6 8 10 9
|
||||
|
||||
var wait = {
|
||||
'1': 10,
|
||||
'2': 25,
|
||||
'3': 10,
|
||||
'4': 10,
|
||||
'5': 20,
|
||||
'6': 30,
|
||||
'7': 10,
|
||||
'8': 15,
|
||||
'9': 30,
|
||||
'10': 10,
|
||||
};
|
||||
|
||||
// 1324
|
||||
|
||||
var result = '';
|
||||
var expectedResult = '13245768109';
|
||||
var counter = 0;
|
||||
|
||||
var checkCounter = function(id, next) {
|
||||
console.log('test queue 3 - Run task: ' + id);
|
||||
// Keep a counter
|
||||
counter++;
|
||||
// push id to result
|
||||
Meteor.setTimeout(function() {
|
||||
result += id;
|
||||
// call next task
|
||||
next();
|
||||
}, wait[id] * 5); // give it a factor 2 to make sure we get the correct result
|
||||
};
|
||||
|
||||
|
||||
// Add the tasks to the queue
|
||||
queue.add(function(next) { checkCounter('1', next); });
|
||||
queue.add(function(next) { checkCounter('2', next); });
|
||||
queue.add(function(next) { checkCounter('3', next); });
|
||||
queue.add(function(next) { checkCounter('4', next); });
|
||||
queue.add(function(next) { checkCounter('5', next); });
|
||||
queue.add(function(next) { checkCounter('6', next); });
|
||||
queue.add(function(next) { checkCounter('7', next); });
|
||||
queue.add(function(next) { checkCounter('8', next); });
|
||||
queue.add(function(next) { checkCounter('9', next); });
|
||||
queue.add(function(next) { checkCounter('10', next); });
|
||||
|
||||
// Run the queue
|
||||
queue.run();
|
||||
});
|
||||
//Test API:
|
||||
//test.isFalse(v, msg)
|
||||
//test.isTrue(v, msg)
|
||||
//test.equal(actual, expected, message, not)
|
||||
//test.length(obj, len)
|
||||
//test.include(s, v)
|
||||
//test.isNaN(v, msg)
|
||||
//test.isUndefined(v, msg)
|
||||
//test.isNotNull
|
||||
//test.isNull
|
||||
//test.throws(func)
|
||||
//test.instanceOf(obj, klass)
|
||||
//test.notEqual(actual, expected, message)
|
||||
//test.runId()
|
||||
//test.exception(exception)
|
||||
//test.expect_fail()
|
||||
//test.ok(doc)
|
||||
//test.fail(doc)
|
||||
//test.equal(a, b, msg)
|
||||
Loading…
Add table
Add a link
Reference in a new issue