Skip to content

Commit 41d795b

Browse files
committed
send messages by batch
1 parent 2174d01 commit 41d795b

File tree

1 file changed

+48
-36
lines changed

1 file changed

+48
-36
lines changed

lib/server/push.api.js

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ Push.setBadge = function(/* id, count */) {
1414

1515
var isConfigured = false;
1616

17-
var sendWorker = function(task, interval) {
17+
var scheduleTask = function(task, interval) {
1818
if (typeof Push.Log === 'function') {
1919
Push.Log('Push: Send worker started, using interval:', interval);
2020
}
2121
if (Push.debug) {
2222
console.log('Push: Send worker started, using interval: ' + interval);
2323
}
2424

25-
return Meteor.setInterval(function() {
25+
return Meteor.setTimeout(function() {
2626
// xxx: add exponential backoff on error
2727
try {
2828
task();
@@ -668,41 +668,46 @@ Push.Configure = function(options) {
668668
} // Else could not reserve
669669
}; // EO sendNotification
670670

671-
sendWorker(function() {
671+
const processQueue = async function() {
672672

673-
if (isSendingNotification) {
674-
return;
675-
}
673+
if (isSendingNotification) {
674+
return;
675+
}
676676

677-
try {
677+
// Set send fence
678+
isSendingNotification = true;
678679

679-
// Set send fence
680-
isSendingNotification = true;
680+
// var countSent = 0;
681+
var batchSize = options.sendBatchSize || 1;
681682

682-
// var countSent = 0;
683-
var batchSize = options.sendBatchSize || 1;
683+
var now = +new Date();
684684

685-
var now = +new Date();
685+
// Find notifications that are not being or already sent
686+
var pendingNotifications = Push.notifications.find({ $and: [
687+
// Message is not sent
688+
{ sent : false },
689+
// And not being sent by other instances
690+
{ sending: { $lt: now } },
691+
// And not queued for future
692+
{ $or: [
693+
{ delayUntil: { $exists: false } },
694+
{ delayUntil: { $lte: new Date() } }
695+
]
696+
}
697+
]}, {
698+
// Sort by created date
699+
sort: { createdAt: 1 },
700+
limit: batchSize
701+
}).fetch();
686702

687-
// Find notifications that are not being or already sent
688-
var pendingNotifications = Push.notifications.find({ $and: [
689-
// Message is not sent
690-
{ sent : false },
691-
// And not being sent by other instances
692-
{ sending: { $lt: now } },
693-
// And not queued for future
694-
{ $or: [
695-
{ delayUntil: { $exists: false } },
696-
{ delayUntil: { $lte: new Date() } }
697-
]
698-
}
699-
]}, {
700-
// Sort by created date
701-
sort: { createdAt: 1 },
702-
limit: batchSize
703-
});
704703

705-
pendingNotifications.forEach(function(notification) {
704+
if(pendingNotifications.length === 0) {
705+
return scheduleTask(processQueue, options.sendInterval || 15000);
706+
}
707+
708+
await Promise.all(pendingNotifications.map(function(notification) {
709+
return new Promise((resolve, reject) => {
710+
Meteor.defer(() => {
706711
try {
707712
sendNotification(notification);
708713
} catch(error) {
@@ -712,14 +717,21 @@ Push.Configure = function(options) {
712717
if (Push.debug) {
713718
console.log('Push: Could not send notification id: "' + notification._id + '", Error: ' + error.message);
714719
}
720+
} finally {
721+
resolve();
715722
}
716-
}); // EO forEach
717-
} finally {
723+
});
724+
})
725+
})); // EO forEach
718726

719-
// Remove the send fence
720-
isSendingNotification = false;
721-
}
722-
}, options.sendInterval || 15000); // Default every 15th sec
727+
// Remove the send fence
728+
isSendingNotification = false;
729+
730+
processQueue(); // continue asap
731+
732+
}
733+
734+
scheduleTask(processQueue, options.sendInterval || 15000);
723735

724736
} else {
725737
if (Push.debug) {

0 commit comments

Comments
 (0)