added load error recovery mechanism to location feature + cleanup and minor refactoring...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2016-06-04 20:50:37 +03:00
parent 197926a897
commit 9ba18f33ae
4 changed files with 118 additions and 66 deletions

View File

@ -125,10 +125,6 @@ var FileSystemLoaderActions = actions.Actions({
'image-file-read-stat': true,
'image-file-skip-previews': false,
// XXX if true and multiple indexes found, load only the first
// without merging...
'load-first-index-only': false,
},
// XXX should this be more general???
@ -161,6 +157,8 @@ var FileSystemLoaderActions = actions.Actions({
loadIndex: ['- File/Load index',
function(path, from_date, logger){
var that = this
// XXX get a logger...
logger = logger || this.logger
if(path == null){
return
@ -172,9 +170,6 @@ var FileSystemLoaderActions = actions.Actions({
from_date = null
}
// XXX get a logger...
logger = logger || this.logger
// XXX make this load incrementally (i.e. and EventEmitter
// a-la glob)....
//file.loadIndex(path, this.config['index-dir'], logger)
@ -231,8 +226,6 @@ var FileSystemLoaderActions = actions.Actions({
// load the first index...
if(index == null){
// XXX use the logger...
//console.log('LOADING:', k, res)
logger && logger.emit('base index', k, res)
index = part
@ -252,29 +245,23 @@ var FileSystemLoaderActions = actions.Actions({
}
loaded.push(k)
// XXX do a better merge and remove this...
// ...we either need to lazy-load clustered indexes
// or merge, in both cases base_path should reflet
// the fact that we have multiple indexes...
if(that.config['load-first-index-only']){
break
}
}
logger && logger.emit('load index', index)
that.load(index)
that.__location = {
// prepare the location data...
var location = {
path: path,
loaded: loaded,
method: 'loadIndex',
}
if(from_date){
that.__location.from = from_date
location.from = from_date
}
// this is the critical section, after this point we
// are doing the actual loading....
that.recoverableLoad(function(){ that.load(index) }, location)
})
}],
@ -441,23 +428,11 @@ var FileSystemLoaderActions = actions.Actions({
if(path == null){
return
}
// XXX get a logger...
logger = logger || this.logger
var that = this
path = util.normalizePath(path)
// NOTE: we set this before we start the load so as to let
// clients know what we are loading and not force them
// to wait to find out...
// XXX not sure if this is the way to go...
var location =
this.__location = {
path: path,
method: 'loadImages',
}
// get the image list...
return this.getImagesInPath(
path,
@ -466,15 +441,17 @@ var FileSystemLoaderActions = actions.Actions({
logger)
// load the data...
.then(function(imgs){
that.load({
images: imgs,
data: data.Data.fromArray(imgs.keys()),
})
that.recoverableLoad(function(){
// NOTE: we set it again because .load() does a .clear()
// before it starts loading which clears the .location
// too...
that.__location = location
that.load({
images: imgs,
data: data.Data.fromArray(imgs.keys()),
})
}, {
path: path,
method: 'loadImages',
})
})
}],
@ -561,8 +538,8 @@ module.FileSystemLoader = core.ImageGridFeatures.Feature({
tag: 'fs-loader',
depends: [
'fs-info',
'location',
'fs-info',
'tasks',
],
suggested: [
@ -1156,8 +1133,6 @@ module.FileSystemLoaderURLHistory = core.ImageGridFeatures.Feature({
handlers: [
pushToHistory('loadImages'),
pushToHistory('loadIndex'),
pushToHistory('loadPath'),
//pushToHistory('loadNewImages'),
],
})
@ -1400,18 +1375,27 @@ var FileSystemWriterActions = actions.Actions({
}
}],
// Save index...
//
// Returns:
// a promise, when resolved will get the location object as argument.
//
// NOTE: with no arguments this will save index to .location.path
//
// XXX should this return a promise??? ...a clean promise???
// XXX BUG: after .loadImages(..) and without arguments this produces
// a result that is not loaded....
saveIndex: ['- File/',
function(path, logger){
var that = this
// XXX get a logger...
logger = logger || this.logger
path = path || this.location.loaded
path = path && path.length == 1 ? path[0] : path
path = util.normalizePath(path)
// merged index...
// XXX
if(path instanceof Array){
console.error('saving to merged indexes not yet supported...')
@ -1431,12 +1415,12 @@ var FileSystemWriterActions = actions.Actions({
path = this.location.path +'/'+ path
}
// XXX get a logger...
logger = logger || this.logger
// XXX get real base path...
//path = path || this.location.path +'/'+ this.config['index-dir']
// NOTE: this will prevent us from overwriting the location
// after we have loaded something else...
var location = this.location
var index = this.prepareIndexForWrite()
return file.writeIndex(
@ -1446,10 +1430,12 @@ var FileSystemWriterActions = actions.Actions({
path +'/'+ this.config['index-dir'],
index.date,
this.config['index-filename-template'],
logger || this.logger)
logger)
.then(function(){
that.location.method = 'loadIndex'
that.location.from = index.date
location.method = 'loadIndex'
location.from = index.date
return location
})
}],

View File

@ -361,23 +361,25 @@ module.URLHistoryFSWriter = core.ImageGridFeatures.Feature({
handlers: [
['saveIndex',
function(){
// push saved to top...
if(this.config['url-history-push-to-top-on-save']){
this.pushURLToHistory()
// update...
} else {
var l = this.location
var e = this.url_history[l.path]
if(e != null){
e.open = l.method
this.saveURLHistory()
function(res){
var that = this
res.then(function(l){
// push saved to top...
if(that.config['url-history-push-to-top-on-save']){
that.pushURLToHistory(l.path, l.method)
// update...
} else {
this.pushURLToHistory()
var e = that.url_history[l.path]
if(e != null){
e.open = l.method
that.saveURLHistory()
} else {
that.pushURLToHistory(l.path, l.method)
}
}
}
})
}],
],
})

View File

@ -30,6 +30,10 @@ var core = require('features/core')
// .path or .url
var LocationActions = actions.Actions({
config: {
'recover-load-errors-to-previous-location': true,
},
// Format:
// {
// path: <base-path>,
@ -60,6 +64,7 @@ var LocationActions = actions.Actions({
return this.__location
},
// XXX is 'loadIndex' a good default???
set location(value){
// got a path...
if(typeof(value) == typeof('str')){
@ -87,6 +92,7 @@ var LocationActions = actions.Actions({
this.__location = value
// XXX is 'loadIndex' a good default???
var res = this[value.method || 'loadIndex'](path)
// XXX load current...
@ -99,6 +105,64 @@ var LocationActions = actions.Actions({
this.current = cur
}
},
// Wrap the loader and recover if it fails...
//
// .recoverableLoad(loader, new-location)
// -> actions
//
// NOTE: this avoids load loops by attempting to recover only once...
//
// XXX should this be used in .location setter?
recoverableLoad: ['- Location/',
function(loader, location){
// this is the critical section, after this point we
// are doing the actual loading....
try {
// prepare to recover, just in case...
this.__recover = (this.__recover !== false
&& this.config['recover-load-errors-to-previous-location']) ?
this.location
: false
loader()
// NOTE: we are setting this after the load because the
// loader may .clear() the viewer, thus clearing the
// .location too...
this.__location = location
// all went well clear the recovery data...
delete this.__recover
// something bad happened, clear and handle it...
} catch(err){
this.clear()
console.error(err)
// recover to last location...
if(this.__recover){
var l = this.__recover
// NOTE: this will prevent us from entering
// a recover attempt loop...
// ...if the recovery fails we will just
// clear and stop.
this.__recover = false
// do the loading...
this.location = l
// fail...
} else {
// clear the recovery data...
delete this.__recover
// fail...
throw err
}
}
}],
})
module.Location = core.ImageGridFeatures.Feature({

View File

@ -662,7 +662,7 @@ module.ImagesPrototype = {
clone: function(){
return (new Images()).join(this)
return (new Images()).loadJSON(this.dumpJSON())
},
// NOTE: this will join the other data into the current object in-place,
// use .clone() to preserve current data...