Refactor pushStatusHandler to use Parse instead of direct access (#4173)

* Refactors pushStatusHandler to use HTTP interface so we can bind CloudCode hooks

* Handle correctly nested dot atomic operations

* Better handling of restricted class names, add support for afterSave _PushStatus

* Adds simple testing for afterSave(PushStatus)

* Reverts jobStatusHandler

* Addresses fixes

* adds delays to all methods
This commit is contained in:
Florent Vilmart
2017-09-18 15:01:07 -04:00
committed by GitHub
parent a39d045c7d
commit a5ce9fc175
9 changed files with 161 additions and 58 deletions

View File

@@ -1,5 +1,6 @@
import { md5Hash, newObjectId } from './cryptoUtils';
import { logger } from './logger';
import Parse from 'parse/node';
const PUSH_STATUS_COLLECTION = '_PushStatus';
const JOB_STATUS_COLLECTION = '_JobStatus';
@@ -50,6 +51,47 @@ function statusHandler(className, database) {
})
}
function restStatusHandler(className) {
let lastPromise = Promise.resolve();
function create(object) {
lastPromise = lastPromise.then(() => {
return Parse._request(
'POST',
`classes/${className}`,
object,
{ useMasterKey: true }
).then((result) => {
// merge the objects
const response = Object.assign({}, object, result);
return Promise.resolve(response);
});
});
return lastPromise;
}
function update(where, object) {
// TODO: when we have updateWhere, use that for proper interfacing
lastPromise = lastPromise.then(() => {
return Parse._request(
'PUT',
`classes/${className}/${where.objectId}`,
object,
{ useMasterKey: true }).then((result) => {
// merge the objects
const response = Object.assign({}, object, result);
return Promise.resolve(response);
});
});
return lastPromise;
}
return Object.freeze({
create,
update
})
}
export function jobStatusHandler(config) {
let jobStatus;
const objectId = newObjectId(config.objectIdSize);
@@ -103,11 +145,12 @@ export function jobStatusHandler(config) {
});
}
export function pushStatusHandler(config, objectId = newObjectId(config.objectIdSize)) {
export function pushStatusHandler(config, existingObjectId) {
let pushStatus;
const database = config.database;
const handler = statusHandler(PUSH_STATUS_COLLECTION, database);
const handler = restStatusHandler(PUSH_STATUS_COLLECTION);
let objectId = existingObjectId;
const setInitial = function(body = {}, where, options = {source: 'rest'}) {
const now = new Date();
let pushTime = now.toISOString();
@@ -133,8 +176,6 @@ export function pushStatusHandler(config, objectId = newObjectId(config.objectId
pushHash = 'd41d8cd98f00b204e9800998ecf8427e';
}
const object = {
objectId,
createdAt: now,
pushTime,
query: JSON.stringify(where),
payload: payloadString,
@@ -148,7 +189,8 @@ export function pushStatusHandler(config, objectId = newObjectId(config.objectId
ACL: {}
}
return handler.create(object).then(() => {
return handler.create(object).then((result) => {
objectId = result.objectId;
pushStatus = {
objectId
};
@@ -159,12 +201,11 @@ export function pushStatusHandler(config, objectId = newObjectId(config.objectId
const setRunning = function(count) {
logger.verbose(`_PushStatus ${objectId}: sending push to %d installations`, count);
return handler.update({status:"pending", objectId: objectId},
{status: "running", updatedAt: new Date(), count });
{status: "running", count });
}
const trackSent = function(results, UTCOffset, cleanupInstallations = process.env.PARSE_SERVER_CLEANUP_INVALID_INSTALLATIONS) {
const update = {
updatedAt: new Date(),
numSent: 0,
numFailed: 0
};
@@ -236,26 +277,33 @@ export function pushStatusHandler(config, objectId = newObjectId(config.objectId
const complete = function() {
return handler.update({ objectId }, {
status: 'succeeded',
count: {__op: 'Delete'},
updatedAt: new Date()
count: {__op: 'Delete'}
});
}
const fail = function(err) {
if (typeof err === 'string') {
err = { message: err };
}
const update = {
errorMessage: JSON.stringify(err),
status: 'failed',
updatedAt: new Date()
errorMessage: err,
status: 'failed'
}
return handler.update({ objectId }, update);
}
return Object.freeze({
objectId,
const rval = {
setInitial,
setRunning,
trackSent,
complete,
fail
})
};
// define objectId to be dynamic
Object.defineProperty(rval, "objectId", {
get: () => objectId
});
return Object.freeze(rval);
}