gmessages/libgm/response_handler.go

99 lines
2.8 KiB
Go
Raw Normal View History

2023-06-30 11:05:33 +00:00
package libgm
2023-06-30 09:54:08 +00:00
import (
"fmt"
"sync"
"go.mau.fi/mautrix-gmessages/libgm/pblite"
"go.mau.fi/mautrix-gmessages/libgm/binary"
"go.mau.fi/mautrix-gmessages/libgm/routes"
2023-06-30 09:54:08 +00:00
)
type ResponseChan struct {
response *pblite.Response
wg sync.WaitGroup
mu sync.Mutex
2023-06-30 09:54:08 +00:00
}
func (s *SessionHandler) addRequestToChannel(requestId string, actionType binary.ActionType) {
_, notOk := routes.Routes[actionType]
2023-06-30 09:54:08 +00:00
if !notOk {
2023-07-09 20:32:19 +00:00
panic(fmt.Errorf("missing action type: %v", actionType))
2023-06-30 09:54:08 +00:00
}
if msgMap, ok := s.requests[requestId]; ok {
responseChan := &ResponseChan{
response: &pblite.Response{},
wg: sync.WaitGroup{},
mu: sync.Mutex{},
2023-06-30 09:54:08 +00:00
}
responseChan.wg.Add(1)
2023-06-30 09:54:08 +00:00
responseChan.mu.Lock()
msgMap[actionType] = responseChan
2023-06-30 09:54:08 +00:00
} else {
s.requests[requestId] = make(map[binary.ActionType]*ResponseChan)
2023-06-30 09:54:08 +00:00
responseChan := &ResponseChan{
response: &pblite.Response{},
wg: sync.WaitGroup{},
mu: sync.Mutex{},
2023-06-30 09:54:08 +00:00
}
responseChan.wg.Add(1)
2023-06-30 09:54:08 +00:00
responseChan.mu.Lock()
s.requests[requestId][actionType] = responseChan
2023-06-30 09:54:08 +00:00
}
}
func (s *SessionHandler) respondToRequestChannel(res *pblite.Response) {
requestId := res.Data.RequestId
2023-06-30 09:54:08 +00:00
reqChannel, ok := s.requests[requestId]
actionType := res.Data.Action
2023-06-30 09:54:08 +00:00
if !ok {
s.client.Logger.Debug().Any("actionType", actionType).Any("requestId", requestId).Msg("Did not expect response for this requestId")
2023-06-30 09:54:08 +00:00
return
}
actionResponseChan, ok2 := reqChannel[actionType]
2023-06-30 09:54:08 +00:00
if !ok2 {
s.client.Logger.Debug().Any("actionType", actionType).Any("requestId", requestId).Msg("Did not expect response for this actionType")
2023-06-30 09:54:08 +00:00
return
}
actionResponseChan.mu.Lock()
actionResponseChan, ok2 = reqChannel[actionType]
if !ok2 {
s.client.Logger.Debug().Any("actionType", actionType).Any("requestId", requestId).Msg("Ignoring request for action...")
2023-06-30 09:54:08 +00:00
return
}
s.client.Logger.Debug().Any("actionType", actionType).Any("requestId", requestId).Msg("responding to request")
actionResponseChan.response = res
actionResponseChan.wg.Done()
delete(reqChannel, actionType)
if len(reqChannel) == 0 {
delete(s.requests, requestId)
2023-06-30 09:54:08 +00:00
}
actionResponseChan.mu.Unlock()
2023-06-30 09:54:08 +00:00
}
func (s *SessionHandler) WaitForResponse(requestId string, actionType binary.ActionType) (*pblite.Response, error) {
2023-06-30 09:54:08 +00:00
requestResponses, ok := s.requests[requestId]
if !ok {
return nil, fmt.Errorf("no response channel found for request ID: %s (actionType: %v)", requestId, actionType)
2023-06-30 09:54:08 +00:00
}
routeInfo, notFound := routes.Routes[actionType]
if !notFound {
return nil, fmt.Errorf("no action exists for actionType: %v (requestId: %s)", actionType, requestId)
}
responseChan, ok2 := requestResponses[routeInfo.Action]
2023-06-30 09:54:08 +00:00
if !ok2 {
return nil, fmt.Errorf("no response channel found for actionType: %v (requestId: %s)", routeInfo.Action, requestId)
2023-06-30 09:54:08 +00:00
}
responseChan.mu.Unlock()
responseChan.wg.Wait()
return responseChan.response, nil
2023-06-30 09:55:49 +00:00
}