@@ -14,15 +14,15 @@ Push.setBadge = function(/* id, count */) {
1414
1515var 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