mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Notification system queueing and queue limit #996
This commit is contained in:
		
							parent
							
								
									88726bed86
								
							
						
					
					
						commit
						7aa89f16c9
					
				| @ -6,6 +6,7 @@ | ||||
| 
 | ||||
|       <ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" @click.stop="fireTestEventAndSucceed">Fire onTest Event</ui-btn> | ||||
|       <ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" color="red-600" @click.stop="fireTestEventAndFail">Fire & Fail</ui-btn> | ||||
|       <!-- <ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" @click.stop="rapidFireTestEvents">Rapid Fire</ui-btn> --> | ||||
|       <ui-btn v-else-if="notification.enabled" :loading="sendingTest" small class="mr-2" @click.stop="sendTestClick">Test</ui-btn> | ||||
|       <ui-btn v-else :loading="enabling" small color="success" class="mr-2" @click="enableNotification">Enable</ui-btn> | ||||
| 
 | ||||
| @ -52,6 +53,7 @@ export default { | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     // For testing using the onTest event | ||||
|     fireTestEventAndFail() { | ||||
|       this.fireTestEvent(true) | ||||
|     }, | ||||
| @ -74,6 +76,19 @@ export default { | ||||
|           this.testing = false | ||||
|         }) | ||||
|     }, | ||||
|     rapidFireTestEvents() { | ||||
|       this.testing = true | ||||
|       var numFired = 0 | ||||
|       var interval = setInterval(() => { | ||||
|         this.fireTestEvent() | ||||
|         numFired++ | ||||
|         if (numFired > 25) { | ||||
|           this.testing = false | ||||
|           clearInterval(interval) | ||||
|         } | ||||
|       }, 100) | ||||
|     }, | ||||
|     // End testing functions | ||||
|     sendTestClick() { | ||||
|       const payload = { | ||||
|         message: `Trigger this notification with test data?`, | ||||
|  | ||||
| @ -7,7 +7,8 @@ class NotificationManager { | ||||
|     this.db = db | ||||
|     this.emitter = emitter | ||||
| 
 | ||||
|     this.notificationFailedMap = {} | ||||
|     this.sendingNotification = false | ||||
|     this.notificationQueue = [] | ||||
|   } | ||||
| 
 | ||||
|   getData() { | ||||
| @ -35,7 +36,10 @@ class NotificationManager { | ||||
|   } | ||||
| 
 | ||||
|   async triggerNotification(eventName, eventData, intentionallyFail = false) { | ||||
|     if (!this.db.notificationSettings.isUseable) return false | ||||
|     if (!this.db.notificationSettings.isUseable) return | ||||
| 
 | ||||
|     // Will queue the notification if sendingNotification and queue is not full
 | ||||
|     if (!this.checkTriggerNotification(eventName, eventData)) return | ||||
| 
 | ||||
|     const notifications = this.db.notificationSettings.getActiveNotificationsForEvent(eventName) | ||||
|     for (const notification of notifications) { | ||||
| @ -44,7 +48,7 @@ class NotificationManager { | ||||
| 
 | ||||
|       notification.updateNotificationFired(success) | ||||
|       if (!success) { // Failed notification
 | ||||
|         if (notification.numConsecutiveFailedAttempts > 2) { | ||||
|         if (notification.numConsecutiveFailedAttempts >= this.db.notificationSettings.maxFailedAttempts) { | ||||
|           Logger.error(`[NotificationManager] triggerNotification: ${notification.eventName}/${notification.id} reached max failed attempts`) | ||||
|           notification.enabled = false | ||||
|         } else { | ||||
| @ -55,9 +59,36 @@ class NotificationManager { | ||||
| 
 | ||||
|     await this.db.updateEntity('settings', this.db.notificationSettings) | ||||
|     this.emitter('notifications_updated', this.db.notificationSettings) | ||||
| 
 | ||||
|     this.notificationFinished() | ||||
|   } | ||||
| 
 | ||||
|   // Return TRUE if notification should be triggered now
 | ||||
|   checkTriggerNotification(eventName, eventData) { | ||||
|     if (this.sendingNotification) { | ||||
|       if (this.notificationQueue.length >= this.db.notificationSettings.maxNotificationQueue) { | ||||
|         Logger.warn(`[NotificationManager] Notification queue is full - ignoring event ${eventName}`) | ||||
|       } else { | ||||
|         Logger.debug(`[NotificationManager] Queueing notification ${eventName} (Queue size: ${this.notificationQueue.length})`) | ||||
|         this.notificationQueue.push({ eventName, eventData }) | ||||
|       } | ||||
|       return false | ||||
|     } | ||||
|     this.sendingNotification = true | ||||
|     return true | ||||
|   } | ||||
| 
 | ||||
|   notificationFinished() { | ||||
|     // Delay between events then run next notification in queue
 | ||||
|     setTimeout(() => { | ||||
|       this.sendingNotification = false | ||||
|       if (this.notificationQueue.length) { // Send next notification in queue
 | ||||
|         const nextNotificationEvent = this.notificationQueue.shift() | ||||
|         this.triggerNotification(nextNotificationEvent.eventName, nextNotificationEvent.eventData) | ||||
|       } | ||||
|     }, this.db.notificationSettings.notificationDelay) | ||||
|   } | ||||
| 
 | ||||
|   sendTestNotification(notification) { | ||||
|     const eventData = notificationData.events.find(e => e.name === notification.eventName) | ||||
|     if (!eventData) { | ||||
|  | ||||
| @ -7,6 +7,9 @@ class NotificationSettings { | ||||
|     this.appriseType = 'api' | ||||
|     this.appriseApiUrl = null | ||||
|     this.notifications = [] | ||||
|     this.maxFailedAttempts = 5 | ||||
|     this.maxNotificationQueue = 20 // once reached events will be ignored
 | ||||
|     this.notificationDelay = 1000 // ms delay between firing notifications
 | ||||
| 
 | ||||
|     if (settings) { | ||||
|       this.construct(settings) | ||||
| @ -17,6 +20,9 @@ class NotificationSettings { | ||||
|     this.appriseType = settings.appriseType | ||||
|     this.appriseApiUrl = settings.appriseApiUrl || null | ||||
|     this.notifications = (settings.notifications || []).map(n => new Notification(n)) | ||||
|     this.maxFailedAttempts = settings.maxFailedAttempts || 5 | ||||
|     this.maxNotificationQueue = settings.maxNotificationQueue || 20 | ||||
|     this.notificationDelay = settings.notificationDelay || 1000 | ||||
|   } | ||||
| 
 | ||||
|   toJSON() { | ||||
| @ -24,7 +30,10 @@ class NotificationSettings { | ||||
|       id: this.id, | ||||
|       appriseType: this.appriseType, | ||||
|       appriseApiUrl: this.appriseApiUrl, | ||||
|       notifications: this.notifications.map(n => n.toJSON()) | ||||
|       notifications: this.notifications.map(n => n.toJSON()), | ||||
|       maxFailedAttempts: this.maxFailedAttempts, | ||||
|       maxNotificationQueue: this.maxNotificationQueue, | ||||
|       notificationDelay: this.notificationDelay | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user