long poll routing first version
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
@ -56,7 +57,10 @@ func (r *RedisRouter) Route(msg *meowlib.ToServerMessage) (*meowlib.FromServerMe
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg.Timeout > 0 {
|
||||
// set timeout for the lookup
|
||||
r.subscribe(msg)
|
||||
}
|
||||
}
|
||||
// manage Matriochka
|
||||
if msg.MatriochkaMessage != nil {
|
||||
@ -165,6 +169,61 @@ func (r *RedisRouter) checkForMessage(msg *meowlib.ToServerMessage) (*meowlib.Fr
|
||||
return &from_server, nil
|
||||
}
|
||||
|
||||
func goSubscribeAndListen(client *redis.Client, key string, messages chan<- string, wg *sync.WaitGroup, done <-chan struct{}) {
|
||||
defer wg.Done()
|
||||
pubsub := client.Subscribe(key)
|
||||
defer pubsub.Close()
|
||||
|
||||
// Create a new channel for the messages from this subscription
|
||||
myMessages := make(chan *redis.Message)
|
||||
go func() {
|
||||
for {
|
||||
msg, err := pubsub.ReceiveMessage()
|
||||
if err != nil {
|
||||
close(myMessages)
|
||||
return
|
||||
}
|
||||
myMessages <- msg
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for a message or for the done signal
|
||||
select {
|
||||
case msg := <-myMessages:
|
||||
messages <- msg.Payload
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RedisRouter) subscribe(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
|
||||
var from_server meowlib.FromServerMessage
|
||||
// update messages counter
|
||||
err := r.Client.Incr("statistics:messages:messagessubscription").Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
messages := make(chan string)
|
||||
var wg sync.WaitGroup
|
||||
done := make(chan struct{})
|
||||
// extract lookup keys and subscribe
|
||||
for _, rq := range msg.PullRequest {
|
||||
wg.Add(1)
|
||||
// subscribe to the lookup key
|
||||
go goSubscribeAndListen(r.Client, rq.LookupKey, messages, &wg, done)
|
||||
}
|
||||
// wait for timeout or message
|
||||
select {
|
||||
case <-messages:
|
||||
close(done)
|
||||
return r.checkForMessage(msg)
|
||||
case <-time.After(10 * time.Second): // 10 seconds timeout
|
||||
close(done)
|
||||
}
|
||||
wg.Wait()
|
||||
return &from_server, nil
|
||||
}
|
||||
|
||||
func (r *RedisRouter) handleInvitation(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
|
||||
var from_server meowlib.FromServerMessage
|
||||
// update messages counter
|
||||
|
Reference in New Issue
Block a user