queue actions seem to be almost done -- still need pretty printing to be pretty ;)

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-12-17 18:57:14 +03:00
parent 9d17474e3d
commit 9c72528908
5 changed files with 122 additions and 38 deletions

View File

@ -2650,7 +2650,7 @@ function(title, func){
// -> [items, ...args]
//
// Prepare args in sync mode...
// arg_handler(undefined, items, ...args)
// arg_handler('sync', items, ...args)
// -> [items, ...args]
//
//
@ -2670,12 +2670,12 @@ function(title, func){
//
// This is different from queuedAction(..) in that what is queued is not
// the action itself but rather the first argument to that action and the
// action itself is used by the queue to handle each item. The rest of
// the arguments are passed to each call.
// action is used by the queue to handle each item. The rest of the
// arguments are passed to each call.
//
// In 'sync' mode the action is run outside of queue/task right away, this
// is done because for a queue we can only control the sync start, i.e.
// the first task execution, the rest of depends on queue configuration
// the first task execution, the rest depends on queue configuration
// thus making the final behaviour unpredictable.
//
//
@ -2683,6 +2683,12 @@ function(title, func){
// logging is handled by the queue/task which is not created in sync
// mode.
// NOTE: since the sync-mode can block it must be used very carefully.
// NOTE: for an example of chaining several queues see features/examples's:
// .exampleChainedQueueHandler(..)
// NOTE: when chaining queues, in 'sync' mode all queues in the chain will
// be run sync...
// NOTE: when chaining arg_handler(..) will get one queue per level of
// chaining, but in 'sync' mode only one 'sync' is passed...
//
// XXX might be a good idea to split this into a generic and domain parts
// and move the generic part into types/runner...
@ -2722,8 +2728,11 @@ function(title, func){
items
: [items])
.map(function(item){
return func.call(that, item, ...args) })) }
var res = func.call(that, item, ...args)
return res === runner.SKIP ?
[]
: [res] })
.flat()) }
// queue mode...
} else {
// prep queue...
@ -2751,13 +2760,15 @@ function(title, func){
// pre-process args...
arg_handler
&& (inputs = arg_handler.call(this, q, ...inputs))
&& (inputs = arg_handler.call(this,
sync == 'sync' ?
sync
: q,
...inputs))
// run...
return (inputs instanceof Promise
|| inputs instanceof runner.FinalizableQueue) ?
// XXX BUG? .then(resolve) is triggered even if inputs was
// stopped (should not resolve) or aborted (should reject)...
inputs.then(
function(items){
return run([items, ...args]) },
@ -2768,11 +2779,11 @@ function(title, func){
title,
toString: function(){
// XXX add opts of given...
return `core.queueHandler('${action.name}',\n\t${
return `core.queueHandler('${action.name}',\n${
(arg_handler ?
object.normalizeIndent( '\t'+ arg_handler.toString() ) + ',\n\t'
object.normalizeIndent('\t'+arg_handler.toString()).indent('\t') + ',\n'
: '')
+ object.normalizeIndent( '\t'+ func.toString() ) })` },
+ object.normalizeIndent('\t'+func.toString()).indent('\t') })` },
}) }
var sessionQueueHandler =
@ -2789,7 +2800,6 @@ function(title, func){
// XXX add a task manager UI...
// XXX might be a good idea to confirm session task stops when loading a
// new index...
// XXX do we need to cache the lister props???
var TaskActions = actions.Actions({
// Tasks...

View File

@ -7,6 +7,8 @@
(function(require){ var module={} // make module AMD/node compatible...
/*********************************************************************/
var runner = require('lib/types/runner')
var toggler = require('lib/toggler')
var actions = require('lib/actions')
var features = require('lib/features')
@ -322,7 +324,7 @@ var ExampleActions = actions.Actions({
function(item, ...args){
console.log('Queue handler action!!', item, ...args)
return new Promise(function(resolve){
setTimeout(resolve, 100) }) })],
setTimeout(function(){ resolve(item) }, 100) }) })],
exampleQueueHandlerActionWArgs: ['- Test/',
core.queueHandler('Example queue handler with arguments',
{quiet: true},
@ -339,29 +341,44 @@ var ExampleActions = actions.Actions({
function(item, timeout, ...args){
console.log('Queue handler action!!', item, timeout, ...args)
return new Promise(function(resolve){
setTimeout(resolve, timeout || 100) }) })],
setTimeout(function(){ resolve(item) }, timeout || 100) }) })],
exampleChainedQueueHandler: ['- Test/',
core.queueHandler('Main queue',
core.queueHandler('Sub queue',
// pre-prepare the inputs (sync)...
function(queue, next, items, ...args){
console.log('### PRE-PREP', items, ...args)
// NOTE: here we will get both the "Sub queue" queue (queue)
// and the "Main queue" queue (next), but when called
// 'sync' no queues are created and only 'sync' is
// passed as first argument...
if(queue == 'sync'){
var [queue, items, ...args] = arguments }
console.log('\tPRE-PREP', items, ...args)
return [items, queue, ...args] },
//return [items, inner_queue, ...args] },
// prepare inputs (async/queue)...
function(item, q, ...args){
console.log('### PREP', q.state, item, ...args)
console.log('\tPREP', item, ...args)
// abort/stop queue...
item == 'abort'
&& q.abort()
&& console.log('### ABORT', q)
&& console.log('\t\tABORT', q)
item == 'stop'
&& q.stop()
&& console.log('### STOP')
&& console.log('\t\tSTOP')
// skip strings...
if(typeof(item) == typeof('str')){
console.log('\t\tSKIP', item)
return runner.SKIP }
return item+1 }),
// handle inputs (async/queue)...
function(item, ...args){
console.log('### HANDLE', item, ...args)
console.log('\tHANDLE', item, ...args)
return item*2 }) ],
})

View File

@ -190,7 +190,7 @@ var SharpActions = actions.Actions({
// XXX revise return values...
// XXX make backup name pattern configurable...
// XXX CROP ready for crop support...
makeResizedImage: ['- Image/',
_makeResizedImage: ['- Image/',
core.doc`Make resized image(s)...
.makeResizedImage(gid, size, path[, options])
@ -393,7 +393,7 @@ var SharpActions = actions.Actions({
// XXX what should we return???
return to }) }) }) })],
_makeResizedImage: ['- Image/',
_makeResizedImage2: ['- Image/',
core.doc`Make resized image(s)...
.makeResizedImage(gid, size, path[, options])
@ -619,16 +619,72 @@ var SharpActions = actions.Actions({
// i.e. call the second queue generator when the first one completes...
// or in other works chain queues -- essentially this is like
// calling .then(..) on a queue but doing it at definition...
makeResizedImage2: ['- Image/',
core.doc`
makeResizedImage: ['- Image/',
core.doc`Make resized image(s)...
.makeResizedImage(gid, size, path[, options])
.makeResizedImage(gids, size, path[, options])
-> promise
Image size formats:
500px - resize to make image's *largest* dimension 500 pixels (default).
500p - resize to make image's *smallest* dimension 500 pixels.
500 - same as 500px
options format:
{
// output image name / name pattern...
//
// NOTE: for multiple images this should be a pattern and not an
// explicit name...
// NOTE: if not given this defaults to: "%n"
name: null | <str>,
// image name pattern data...
//
// NOTE: for more info on pattern see: .formatImageName(..)
data: null | { .. },
// if true and image is smaller than size enlarge it...
//
// default: null / false
enlarge: null | true,
// overwrite, backup or skip (default) existing images...
//
// default: null / false
overwrite: null | true | 'backup',
// if true do not write an image if it's smaller than size...
//
// default: null / false
skipSmaller: null | true,
// XXX not implemented...
transform: ...,
crop: ...,
timestamp: ...,
logger: ...,
, }
NOTE: all options are optional.
NOTE: this will not overwrite existing images.
`,
core.queueHandler('Making resized image',
// prepare the data for image resizing (session queue)...
core.sessionQueueHandler('Gathering image data for resizing',
// prepare the input index-dependant data in a fast way...
function(inner_queue, outer_queue, images, size, path, options){
function(queue, _, images, size, path, options){
var n = arguments.length - 1
if(queue == 'sync'){
n--
var [queue, images, size, path, options] = arguments }
// sanity check...
if(arguments.length < 4){
if(n < 3){
throw new Error('.makeResizedImage(..): '
+'need at least: images, size and path.') }
return [
@ -653,7 +709,7 @@ var SharpActions = actions.Actions({
// skip non-images...
if(!image || !['image', null, undefined]
.includes(image.type)){
return [] }
return runner.SKIP }
return [
// source...
this.getImagePath(gid),
@ -676,8 +732,9 @@ var SharpActions = actions.Actions({
] }),
// do the actual resizing (global queue)...
function([source, to, image], size, _, options={}){
// XXX handle skipped items -- source, to and image are undefined...
// XXX
// handle skipped items -- source, to and image are undefined...
if(source == null){
return undefined }
// sizing...
var fit =

View File

@ -1204,14 +1204,14 @@
}
},
"ig-object": {
"version": "5.4.12",
"resolved": "https://registry.npmjs.org/ig-object/-/ig-object-5.4.12.tgz",
"integrity": "sha512-9kZM80Js9/eTwXN9VXwLDC1wDJ7gIAdYU9GIzb5KJmNcLAMaW+zhgFrwFFMrcSfggUuadgnqSrS41E4XLe8JZw=="
"version": "5.4.13",
"resolved": "https://registry.npmjs.org/ig-object/-/ig-object-5.4.13.tgz",
"integrity": "sha512-6qJjoDWZ4VmXJvga3LoFH7/JmUoOZuGC73iG54hC8uvv8CAOAMTwTpMm4c2kKAeZ+HdA1sHfa1cjSPVbElmUTA=="
},
"ig-types": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ig-types/-/ig-types-6.0.1.tgz",
"integrity": "sha512-yaZU07JZO+9lxPGUjxnvRCGAXyAXSqP9ef33eW8912E751RAUyexruPaJkalvJuRJYzMo6rrURk65asWUNGs/g==",
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/ig-types/-/ig-types-6.0.4.tgz",
"integrity": "sha512-6127GzvMz1Ow8Qizbs0vEvMdYsOJR9HVs0By8dQJIYnX2RRAviUStI+E/wwEH/OxHZpkmFHxwZ6xvmC0S7KP3w==",
"requires": {
"ig-object": "^5.4.12",
"object-run": "^1.0.1"

View File

@ -33,8 +33,8 @@
"ig-actions": "^3.24.24",
"ig-argv": "^2.16.3",
"ig-features": "^3.4.2",
"ig-object": "^5.4.12",
"ig-types": "^6.0.1",
"ig-object": "^5.4.13",
"ig-types": "^6.0.4",
"json5": "^2.1.3",
"object-run": "^1.0.1",
"requirejs": "^2.3.6",