Files
kami-parse-server/src/pushStatusHandler.js
Florent Vilmart bc96f0beb1 Adds X-Parse-Push-Status-Id header (#1412)
* Adds X-Parse-Push-Status-Id header

* Waits for _PushStatus to be stored
2016-04-07 18:08:09 -04:00

121 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { md5Hash, newObjectId } from './cryptoUtils';
import { logger } from './logger';
export function flatten(array) {
return array.reduce((memo, element) => {
if (Array.isArray(element)) {
memo = memo.concat(flatten(element));
} else {
memo = memo.concat(element);
}
return memo;
}, []);
}
export default function pushStatusHandler(config) {
let initialPromise;
let pushStatus;
let objectId = newObjectId();
let collection = function() {
return config.database.adaptiveCollection('_PushStatus');
}
let setInitial = function(body = {}, where, options = {source: 'rest'}) {
let now = new Date();
let data = body.data || {};
let object = {
objectId,
pushTime: now.toISOString(),
_created_at: now,
query: JSON.stringify(where),
payload: body.data,
source: options.source,
title: options.title,
expiry: body.expiration_time,
status: "pending",
numSent: 0,
pushHash: md5Hash(JSON.stringify(data)),
// lockdown!
_wperm: [],
_rperm: []
}
initialPromise = collection().then((collection) => {
return collection.insertOne(object);
}).then((res) => {
pushStatus = {
objectId: object.objectId
};
return Promise.resolve(pushStatus);
})
return initialPromise;
}
let setRunning = function(installations) {
logger.verbose('sending push to %d installations', installations.length);
return initialPromise.then(() => {
return collection();
}).then((collection) => {
return collection.updateOne({status:"pending", objectId: pushStatus.objectId}, {$set: {status: "running"}});
});
}
let complete = function(results) {
let update = {
status: 'succeeded',
numSent: 0,
numFailed: 0,
};
if (Array.isArray(results)) {
results = flatten(results);
results.reduce((memo, result) => {
// Cannot handle that
if (!result.device || !result.device.deviceType) {
return memo;
}
let deviceType = result.device.deviceType;
if (result.transmitted)
{
memo.numSent++;
memo.sentPerType = memo.sentPerType || {};
memo.sentPerType[deviceType] = memo.sentPerType[deviceType] || 0;
memo.sentPerType[deviceType]++;
} else {
memo.numFailed++;
memo.failedPerType = memo.failedPerType || {};
memo.failedPerType[deviceType] = memo.failedPerType[deviceType] || 0;
memo.failedPerType[deviceType]++;
}
return memo;
}, update);
}
logger.verbose('sent push! %d success, %d failures', update.numSent, update.numFailed);
return initialPromise.then(() => {
return collection();
}).then((collection) => {
return collection.updateOne({status:"running", objectId: pushStatus.objectId}, {$set: update});
});
}
let fail = function(err) {
let update = {
errorMessage: JSON.stringify(err),
status: 'failed'
}
logger.error('error while sending push', err);
return initialPromise.then(() => {
return collection();
}).then((collection) => {
return collection.updateOne({objectId: pushStatus.objectId}, {$set: update});
});
}
return Object.freeze({
objectId,
setInitial,
setRunning,
complete,
fail
})
}