Move the stopwatches to the eventsource stream (#14588)
Move the stopwatches to the eventsource stream Use the /user/events eventsource to update the stopwatches instead of polling /api/v1/user/stopwatches if the eventsource is enabled. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
		
							parent
							
								
									430b3b7806
								
							
						
					
					
						commit
						092299891f
					
				| @ -5,13 +5,17 @@ | ||||
| package events | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/convert" | ||||
| 	"code.gitea.io/gitea/modules/eventsource" | ||||
| 	"code.gitea.io/gitea/modules/graceful" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/routers/user" | ||||
| ) | ||||
| 
 | ||||
| @ -55,6 +59,8 @@ func Events(ctx *context.Context) { | ||||
| 
 | ||||
| 	timer := time.NewTicker(30 * time.Second) | ||||
| 
 | ||||
| 	stopwatchTimer := time.NewTicker(setting.UI.Notification.MinTimeout) | ||||
| 
 | ||||
| loop: | ||||
| 	for { | ||||
| 		select { | ||||
| @ -75,6 +81,32 @@ loop: | ||||
| 		case <-shutdownCtx.Done(): | ||||
| 			go unregister() | ||||
| 			break loop | ||||
| 		case <-stopwatchTimer.C: | ||||
| 			sws, err := models.GetUserStopwatches(ctx.User.ID, models.ListOptions{}) | ||||
| 			if err != nil { | ||||
| 				log.Error("Unable to GetUserStopwatches: %v", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			apiSWs, err := convert.ToStopWatches(sws) | ||||
| 			if err != nil { | ||||
| 				log.Error("Unable to APIFormat stopwatches: %v", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			dataBs, err := json.Marshal(apiSWs) | ||||
| 			if err != nil { | ||||
| 				log.Error("Unable to marshal stopwatches: %v", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			_, err = (&eventsource.Event{ | ||||
| 				Name: "stopwatches", | ||||
| 				Data: string(dataBs), | ||||
| 			}).WriteTo(ctx.Resp) | ||||
| 			if err != nil { | ||||
| 				log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err) | ||||
| 				go unregister() | ||||
| 				break loop | ||||
| 			} | ||||
| 			ctx.Resp.Flush() | ||||
| 		case event, ok := <-messageChan: | ||||
| 			if !ok { | ||||
| 				break loop | ||||
|  | ||||
| @ -12,6 +12,7 @@ class Source { | ||||
|     this.listen('open'); | ||||
|     this.listen('logout'); | ||||
|     this.listen('notification-count'); | ||||
|     this.listen('stopwatches'); | ||||
|     this.listen('error'); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -17,7 +17,58 @@ export async function initStopwatch() { | ||||
|     $(this).parent().trigger('submit'); | ||||
|   }); | ||||
| 
 | ||||
|   if (!stopwatchEl || NotificationSettings.MinTimeout <= 0) { | ||||
|   if (!stopwatchEl) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (NotificationSettings.EventSourceUpdateTime > 0 && !!window.EventSource && window.SharedWorker) { | ||||
|     // Try to connect to the event source via the shared worker first
 | ||||
|     const worker = new SharedWorker(`${__webpack_public_path__}js/eventsource.sharedworker.js`, 'notification-worker'); | ||||
|     worker.addEventListener('error', (event) => { | ||||
|       console.error(event); | ||||
|     }); | ||||
|     worker.port.onmessageerror = () => { | ||||
|       console.error('Unable to deserialize message'); | ||||
|     }; | ||||
|     worker.port.postMessage({ | ||||
|       type: 'start', | ||||
|       url: `${window.location.origin}${AppSubUrl}/user/events`, | ||||
|     }); | ||||
|     worker.port.addEventListener('message', (event) => { | ||||
|       if (!event.data || !event.data.type) { | ||||
|         console.error(event); | ||||
|         return; | ||||
|       } | ||||
|       if (event.data.type === 'stopwatches') { | ||||
|         updateStopwatchData(JSON.parse(event.data.data)); | ||||
|       } else if (event.data.type === 'error') { | ||||
|         console.error(event.data); | ||||
|       } else if (event.data.type === 'logout') { | ||||
|         if (event.data !== 'here') { | ||||
|           return; | ||||
|         } | ||||
|         worker.port.postMessage({ | ||||
|           type: 'close', | ||||
|         }); | ||||
|         worker.port.close(); | ||||
|         window.location.href = AppSubUrl; | ||||
|       } | ||||
|     }); | ||||
|     worker.port.addEventListener('error', (e) => { | ||||
|       console.error(e); | ||||
|     }); | ||||
|     worker.port.start(); | ||||
|     window.addEventListener('beforeunload', () => { | ||||
|       worker.port.postMessage({ | ||||
|         type: 'close', | ||||
|       }); | ||||
|       worker.port.close(); | ||||
|     }); | ||||
| 
 | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (NotificationSettings.MinTimeout <= 0) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
| @ -59,6 +110,10 @@ async function updateStopwatch() { | ||||
|     updateTimeInterval = null; | ||||
|   } | ||||
| 
 | ||||
|   return updateStopwatchData(data); | ||||
| } | ||||
| 
 | ||||
| async function updateStopwatchData(data) { | ||||
|   const watch = data[0]; | ||||
|   const btnEl = $('.active-stopwatch-trigger'); | ||||
|   if (!watch) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user