Push scalability (#3080)

* Update status through increment
* adds support for incrementing nested keys
* fix issue when having spaces in keys for ordering
* Refactors PushController to use worker
* Adds tests for custom push queue config
* Makes PushController adapter independant
* Better logging of _PushStatus in VERBOSE
This commit is contained in:
Florent Vilmart
2017-01-13 19:34:04 -05:00
committed by GitHub
parent 5f849ca662
commit deedf7b370
20 changed files with 588 additions and 211 deletions

60
src/Push/PushQueue.js Normal file
View File

@@ -0,0 +1,60 @@
import { ParseMessageQueue } from '../ParseMessageQueue';
import rest from '../rest';
import { isPushIncrementing } from './utils';
const PUSH_CHANNEL = 'parse-server-push';
const DEFAULT_BATCH_SIZE = 100;
export class PushQueue {
parsePublisher: Object;
channel: String;
batchSize: Number;
// config object of the publisher, right now it only contains the redisURL,
// but we may extend it later.
constructor(config: any = {}) {
this.channel = config.channel || PUSH_CHANNEL;
this.batchSize = config.batchSize || DEFAULT_BATCH_SIZE;
this.parsePublisher = ParseMessageQueue.createPublisher(config);
}
static defaultPushChannel() {
return PUSH_CHANNEL;
}
enqueue(body, where, config, auth, pushStatus) {
const limit = this.batchSize;
// Order by badge (because the payload is badge dependant)
// and createdAt to fix the order
const order = isPushIncrementing(body) ? 'badge,createdAt' : 'createdAt';
return Promise.resolve().then(() => {
return rest.find(config,
auth,
'_Installation',
where,
{limit: 0, count: true});
}).then(({results, count}) => {
if (!results) {
return Promise.reject({error: 'PushController: no results in query'})
}
pushStatus.setRunning(count);
let skip = 0;
while (skip < count) {
const query = { where,
limit,
skip,
order };
const pushWorkItem = {
body,
query,
pushStatus: { objectId: pushStatus.objectId },
applicationId: config.applicationId
}
this.parsePublisher.publish(this.channel, JSON.stringify(pushWorkItem));
skip += limit;
}
});
}
}