187 lines
4.6 KiB
JavaScript
187 lines
4.6 KiB
JavaScript
/**
|
|
* Delayed writing to staging bucket
|
|
*
|
|
* Copyright (C) 2017 R-T Specialty, LLC.
|
|
*
|
|
* This file is part of liza.
|
|
*
|
|
* liza is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
var Class = require( 'easejs' ).Class,
|
|
StagingBucket = require( './StagingBucket' );
|
|
|
|
|
|
/**
|
|
* Holds changes until explicitly processed to avoid cascades
|
|
*
|
|
* Since each write could trigger any number of event listeners, writes
|
|
* should be queued and done en-masse.
|
|
*/
|
|
module.exports = Class( 'DelayedStagingBucket' )
|
|
.extend( StagingBucket,
|
|
{
|
|
/**
|
|
* Queued data
|
|
* @type {Object}
|
|
*/
|
|
'private _queued': {},
|
|
|
|
/**
|
|
* Delay timer id
|
|
* @type {number}
|
|
*/
|
|
'private _timer': 0,
|
|
|
|
|
|
'public override setValues': function( data, merge_index, merge_null )
|
|
{
|
|
for ( var name in data )
|
|
{
|
|
if ( merge_index )
|
|
{
|
|
if ( this._queued[ name ] === undefined )
|
|
{
|
|
this._queued[ name ] = [];
|
|
}
|
|
|
|
// merge individual indexes
|
|
this.merge( data[ name ], this._queued[ name ] );
|
|
}
|
|
else
|
|
{
|
|
// no index merge; replace any existing data
|
|
this._queued[ name ] = Array.prototype.slice.call(
|
|
data[ name ], 0
|
|
);
|
|
|
|
// this will ensure that no data will follow what we were
|
|
// provided
|
|
this._queued[ name ].push( null );
|
|
}
|
|
}
|
|
|
|
this._setTimer();
|
|
return this;
|
|
},
|
|
|
|
|
|
'private _setTimer': function()
|
|
{
|
|
// no need to re-set timers
|
|
if ( this._timer )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// invoke when stack clears
|
|
var _self = this;
|
|
this._timer = setTimeout( function()
|
|
{
|
|
_self.processValues();
|
|
}, 0 );
|
|
},
|
|
|
|
|
|
/**
|
|
* Retrieve the data that will result after a merge
|
|
*
|
|
* This should be used sparingly, since if this is called before data is
|
|
* actually merged into the bucket, then it is possible that the values will
|
|
* change after validations are run.
|
|
*/
|
|
'public getPendingDataByName': function( name, diff )
|
|
{
|
|
diff = diff || this._queued;
|
|
|
|
var pending = this.getDataByName['super'].call( this, name );
|
|
if ( !( this._queued[ name ] || diff[ name ] ) )
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
// merge the queued data
|
|
this.merge( ( this._queued[ name ] || diff[ name ] ), pending, true );
|
|
return pending;
|
|
},
|
|
|
|
|
|
'public override getDataByName': function( name )
|
|
{
|
|
// if enqueued data is requested, then we have no choice but to merge to
|
|
// ensure that the data is up-to-date
|
|
if ( this._queued[ name ] )
|
|
{
|
|
this.processValues();
|
|
}
|
|
|
|
return this.__super.call( this, name );
|
|
},
|
|
|
|
|
|
'public override getData': function()
|
|
{
|
|
// gah!
|
|
var _s = this.__super;
|
|
this.processValues();
|
|
return _s.call( this );
|
|
},
|
|
|
|
|
|
'public override each': function( c )
|
|
{
|
|
var _s = this.__super;
|
|
this.processValues();
|
|
return _s.call( this, c );
|
|
},
|
|
|
|
|
|
'public override getFilledDiff': function()
|
|
{
|
|
var _s = this.__super;
|
|
this.processValues();
|
|
return _s.call( this );
|
|
},
|
|
|
|
|
|
'public override hasIndex': function( name, i )
|
|
{
|
|
var _s = this.__super;
|
|
this.processValues();
|
|
return _s.call( this, name, i );
|
|
},
|
|
|
|
|
|
'public processValues': function()
|
|
{
|
|
// if no timer is set, then we have no data
|
|
if ( !this._timer )
|
|
{
|
|
return this;
|
|
}
|
|
|
|
// since additional data may be queued as a consequence of the below
|
|
// set, prepare for it by providing an empty queue
|
|
var oldqueue = this._queued;
|
|
this._queued = {};
|
|
this._timer = 0;
|
|
|
|
this.setValues['super'].call( this,
|
|
oldqueue, true, true
|
|
);
|
|
|
|
return this;
|
|
}
|
|
} );
|