mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-1142] Implement EnqueueWithTimeout and DequeueWithTimeout (#794)
* [NOD-1142] Implement EnqueueWithTimeout and DequeueWithTimeout. * [NOD-1142] Use DequeueWithTimeout in readMsgBlock. * [NOD-1142] Add comments about the new methods.
This commit is contained in:
parent
6076309b3e
commit
f8e53d309c
@ -1,7 +1,9 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/kaspanet/kaspad/wire"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -48,6 +50,37 @@ func (r *Route) Dequeue() (message wire.Message, isOpen bool) {
|
||||
return <-r.channel, true
|
||||
}
|
||||
|
||||
// EnqueueWithTimeout attempts to enqueue a message to the Route
|
||||
// and returns an error if the given timeout expires first.
|
||||
func (r *Route) EnqueueWithTimeout(message wire.Message, timeout time.Duration) (isOpen bool, err error) {
|
||||
if r.closed {
|
||||
return false, nil
|
||||
}
|
||||
if len(r.channel) == maxMessages {
|
||||
r.onCapacityReachedHandler()
|
||||
}
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
return false, errors.New("timeout expired")
|
||||
case r.channel <- message:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// DequeueWithTimeout attempts to dequeue a message from the Route
|
||||
// and returns an error if the given timeout expires first.
|
||||
func (r *Route) DequeueWithTimeout(timeout time.Duration) (message wire.Message, isOpen bool, err error) {
|
||||
if r.closed {
|
||||
return nil, false, nil
|
||||
}
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
return nil, false, errors.New("timeout expired")
|
||||
case message := <-r.channel:
|
||||
return message, true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Route) setOnCapacityReachedHandler(onCapacityReachedHandler onCapacityReachedHandler) {
|
||||
r.onCapacityReachedHandler = onCapacityReachedHandler
|
||||
}
|
||||
|
@ -138,32 +138,22 @@ func readMsgBlock(incomingRoute *router.Route, invsQueue *[]*wire.MsgInvRelayBlo
|
||||
msgBlock *wire.MsgBlock, shouldStop bool, err error) {
|
||||
|
||||
for {
|
||||
closeChan := make(chan struct{})
|
||||
msgChan := make(chan wire.Message)
|
||||
spawn(func() {
|
||||
message, isOpen := incomingRoute.Dequeue()
|
||||
if !isOpen {
|
||||
closeChan <- struct{}{}
|
||||
return
|
||||
}
|
||||
msgChan <- message
|
||||
})
|
||||
|
||||
const timeout = 30 * time.Second
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
return nil, false, errors.Errorf("stalled for %s", timeout)
|
||||
case <-closeChan:
|
||||
message, isOpen, err := incomingRoute.DequeueWithTimeout(timeout)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !isOpen {
|
||||
return nil, true, nil
|
||||
case msg := <-msgChan:
|
||||
switch msg := msg.(type) {
|
||||
case *wire.MsgInvRelayBlock:
|
||||
*invsQueue = append(*invsQueue, msg)
|
||||
case *wire.MsgBlock:
|
||||
return msg, false, nil
|
||||
default:
|
||||
panic(errors.Errorf("unexpected message %s", msg.Command()))
|
||||
}
|
||||
}
|
||||
|
||||
switch message := message.(type) {
|
||||
case *wire.MsgInvRelayBlock:
|
||||
*invsQueue = append(*invsQueue, message)
|
||||
case *wire.MsgBlock:
|
||||
return message, false, nil
|
||||
default:
|
||||
panic(errors.Errorf("unexpected message %s", message.Command()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const pingTimeout = 30 * time.Second
|
||||
|
||||
// ReceivePings handles all ping messages coming through incomingRoute.
|
||||
// This function assumes that incomingRoute will only return MsgPing.
|
||||
func ReceivePings(incomingRoute *router.Route, outgoingRoute *router.Route) error {
|
||||
@ -20,7 +22,10 @@ func ReceivePings(incomingRoute *router.Route, outgoingRoute *router.Route) erro
|
||||
pingMessage := message.(*wire.MsgPing)
|
||||
|
||||
pongMessage := wire.NewMsgPong(pingMessage.Nonce)
|
||||
isOpen = outgoingRoute.Enqueue(pongMessage)
|
||||
isOpen, err := outgoingRoute.EnqueueWithTimeout(pongMessage, pingTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isOpen {
|
||||
return nil
|
||||
}
|
||||
@ -43,12 +48,18 @@ func SendPings(incomingRoute *router.Route, outgoingRoute *router.Route, peer *p
|
||||
peer.SetPingPending(nonce)
|
||||
|
||||
pingMessage := wire.NewMsgPing(nonce)
|
||||
isOpen := outgoingRoute.Enqueue(pingMessage)
|
||||
isOpen, err := outgoingRoute.EnqueueWithTimeout(pingMessage, pingTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isOpen {
|
||||
return nil
|
||||
}
|
||||
|
||||
message, isOpen := incomingRoute.Dequeue()
|
||||
message, isOpen, err := incomingRoute.DequeueWithTimeout(pingTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isOpen {
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user