[Persistence] Refactor persistence queue

Refactor/rename persistence queue to handle dependency injection
in a single place. WTD-1033.
This commit is contained in:
Victor Woeltjen 2015-03-20 13:06:49 -07:00
parent 356bd2de88
commit f0549db4fa
3 changed files with 131 additions and 72 deletions

View File

@ -1,90 +1,55 @@
/*global define*/ /*global define*/
define( define(
['./QueuedPersistenceHandler'], [
function (QueuedPersistenceHandler) { './PersistenceQueueImpl',
'./PersistenceQueueHandler',
'./PersistenceFailureHandler'
],
function (
PersistenceQueueImpl,
PersistenceQueueHandler,
PersistenceFailureHandler
) {
"use strict"; "use strict";
/** /**
* The PersistenceQueue is used by the QueuingPersistenceCapability * The PersistenceQueue is used by the QueuingPersistenceCapability
* to aggregrate calls for object persistence. These are then issued * to aggregrate calls for object persistence. These are then issued
* in a group, such that if some or all are rejected, this result can * in a group, such that if some or all are rejected, this result can
* be shown to the user (again, in a group.) * be shown to the user (again, in a group.)
* *
* @param $q Angular's $q * This constructor is exposed as a service, but handles only the
* wiring of injected dependencies; behavior is implemented in the
* various component parts.
*
* @param $timeout Angular's $timeout * @param $timeout Angular's $timeout
* @param {DialogService} dialogService services to prompt for user * @param {PersistenceQueueHandler} handler handles actual
* input if persistence fails * persistence when the queue is flushed
* @param {number} [DELAY] optional; delay in milliseconds between * @param {number} [DELAY] optional; delay in milliseconds between
* attempts to flush the queue * attempts to flush the queue
*/ */
function PersistenceQueue($q, $timeout, dialogService, DELAY) { function PersistenceQueue(
var queue = {}, $q,
objects = {}, $timeout,
lastObservedSize = 0, dialogService,
handler = new QueuedPersistenceHandler($q, dialogService), persistenceService,
pendingTimeout, PERSISTENCE_QUEUE_DELAY
flushPromise; ) {
// Wire up injected dependencies
// Check if the queue's size has stopped increasing) return new PersistenceQueueImpl(
function quiescent() { $timeout,
return Object.keys(queue).length === lastObservedSize; new PersistenceQueueHandler(
} $q,
new PersistenceFailureHandler(
// Persist all queued objects $q,
function flush() { dialogService,
// Persist all queued objects persistenceService
flushPromise = handler.persist(queue, objects); )
),
// When persisted, clear the active promise PERSISTENCE_QUEUE_DELAY
flushPromise.then(function () { );
flushPromise = undefined;
});
// Reset queue, etc.
queue = {};
objects = {};
lastObservedSize = 0;
pendingTimeout = undefined;
}
// Schedule a flushing of the queue (that is, plan to flush
// all objects in the queue)
function scheduleFlush() {
function maybeFlush() {
// Only flush when we've stopped receiving updates
(quiescent() ? flush : scheduleFlush)();
}
// If we are already flushing the queue...
if (flushPromise) {
// Wait until that's over before considering a flush
flushPromise.then(maybeFlush);
} else {
// Otherwise, schedule a flush on a timeout (to give
// a window for other updates to get aggregated)
pendingTimeout = pendingTimeout ||
$timeout(maybeFlush, DELAY, false);
}
}
// If no delay is provided, use a default
DELAY = DELAY || 0;
return {
/**
* Queue persistence of a domain object.
* @param {DomainObject} domainObject the domain object
* @param {PersistenceCapability} persistence the object's
* undecorated persistence capability
*/
put: function (domainObject, persistence) {
var id = domainObject.getId();
queue[id] = persistence;
objects[id] = domainObject;
scheduleFlush();
}
};
} }
return PersistenceQueue; return PersistenceQueue;

View File

@ -0,0 +1,94 @@
/*global define*/
define(
[],
function () {
"use strict";
/**
* The PersistenceQueue is used by the QueuingPersistenceCapability
* to aggregrate calls for object persistence. These are then issued
* in a group, such that if some or all are rejected, this result can
* be shown to the user (again, in a group.)
*
* This implementation is separate out from PersistenceQueue, which
* handles the wiring of injected dependencies into an instance of
* this class.
*
* @param $timeout Angular's $timeout
* @param {PersistenceQueueHandler} handler handles actual
* persistence when the queue is flushed
* @param {number} [DELAY] optional; delay in milliseconds between
* attempts to flush the queue
*/
function PersistenceQueueImpl($timeout, handler, DELAY) {
var queue = {},
objects = {},
lastObservedSize = 0,
pendingTimeout,
flushPromise;
// Check if the queue's size has stopped increasing)
function quiescent() {
return Object.keys(queue).length === lastObservedSize;
}
// Persist all queued objects
function flush() {
// Persist all queued objects
flushPromise = handler.persist(queue, objects);
// When persisted, clear the active promise
flushPromise.then(function () {
flushPromise = undefined;
});
// Reset queue, etc.
queue = {};
objects = {};
lastObservedSize = 0;
pendingTimeout = undefined;
}
// Schedule a flushing of the queue (that is, plan to flush
// all objects in the queue)
function scheduleFlush() {
function maybeFlush() {
// Only flush when we've stopped receiving updates
(quiescent() ? flush : scheduleFlush)();
}
// If we are already flushing the queue...
if (flushPromise) {
// Wait until that's over before considering a flush
flushPromise.then(maybeFlush);
} else {
// Otherwise, schedule a flush on a timeout (to give
// a window for other updates to get aggregated)
pendingTimeout = pendingTimeout ||
$timeout(maybeFlush, DELAY, false);
}
}
// If no delay is provided, use a default
DELAY = DELAY || 0;
return {
/**
* Queue persistence of a domain object.
* @param {DomainObject} domainObject the domain object
* @param {PersistenceCapability} persistence the object's
* undecorated persistence capability
*/
put: function (domainObject, persistence) {
var id = domainObject.getId();
queue[id] = persistence;
objects[id] = domainObject;
scheduleFlush();
}
};
}
return PersistenceQueueImpl;
}
);