Fix deadlocks in event listener system; closes pterodactyl/panel#2298

Fixes deadlocks that occurred when events were registered while other events were being unsubscribed and data was being flooded to these listeners. A complete mess, I hate this code, it is going to break again, but jesus I'm so tired.
This commit is contained in:
Dane Everitt
2020-09-11 23:01:54 -07:00
committed by GitHub
parent 45bcb9cd68
commit b2eebcaf6d
7 changed files with 57 additions and 32 deletions

View File

@@ -50,24 +50,26 @@ var e = []string{
// Listens for different events happening on a server and sends them along
// to the connected websocket.
func (h *Handler) ListenForServerEvents(ctx context.Context) {
eventChannel := make(chan events.Event)
for _, event := range e {
h.server.Events().Subscribe(event, eventChannel)
}
h.server.Log().Debug("listening for server events over websocket")
for d := range eventChannel {
eventChannel := make(chan events.Event)
h.server.Events().Subscribe(e, eventChannel)
go func(ctx context.Context) {
select {
case <-ctx.Done():
for _, event := range e {
h.server.Events().Unsubscribe(event, eventChannel)
if h.jwt != nil {
h.server.Log().WithField("jwt_subject", h.jwt.Subject).Debug("unsubscribing server from event listeners")
}
h.server.Events().Unsubscribe(e, eventChannel)
close(eventChannel)
default:
_ = h.SendJson(&Message{
Event: d.Topic,
Args: []string{d.Data},
})
}
}(ctx)
for d := range eventChannel {
if err := h.SendJson(&Message{Event: d.Topic, Args: []string{d.Data}}); err != nil {
h.server.Log().WithField("error", err).Warn("error while sending server data over websocket")
}
}
}

View File

@@ -95,6 +95,8 @@ func (h *Handler) SendJson(v *Message) error {
// Do not send JSON down the line if the JWT on the connection is not
// valid!
if err := h.TokenValid(); err != nil {
h.server.Log().WithField("error", err).Warn("invalid JWT detected for server websocket!")
return nil
}