Skip to content
Permalink
demo-day
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
package main
import (
"errors"
"fmt"
"sync"
"time"
)
var responseManager = &_responseManager{make(map[int]*responseListener), sync.Mutex{}, make(chan int)}
type _responseManager struct {
// Struct to manage which responses we are waiting for
mapping map[int]*responseListener
lock sync.Mutex
resolved chan int
}
type responseListener struct {
// Struct to manage waiting for responses
packet Packet
timer *time.Timer
recv chan error
resend chan Packet
}
func (rman *_responseManager) addPacket(p Packet) { // Add a packet to the response map and start waiting for it
rl := &responseListener{p, time.NewTimer(10 * time.Second), make(chan error), socketClient.packetResend}
rman.lock.Lock() // Safe map access
defer rman.lock.Unlock()
rman.mapping[p.ID] = rl
go rl.awaitResponse() // Start waiting
}
func (rman *_responseManager) received(p Packet) {
rman.lock.Lock()
listener, found := rman.mapping[p.ID] // Get the response listener
rman.lock.Unlock()
if !found {
fmt.Printf("Well, we received a response for packet %v, which is unexpected because there's no listener for it\n", p.ID)
return
}
var err error = nil
message := string(p.Message) // See what the message was
if message != messageReceived { // The only one that's implemented right now is messageReceived so this shouldn't fail
err = errors.New(fmt.Sprintf("Unexpected response message for packet %v: %v\n", p.ID, message))
} else {
fmt.Printf("Got good response for packet %v\n", p.ID)
}
listener.recv <- err
}
func (rman *_responseManager) remove(id int) {
rman.lock.Lock()
defer rman.lock.Unlock()
delete(rman.mapping, id)
}
func (rl *responseListener) awaitResponse() { // Gets a message from the timer or the Recv channel
select {
case <-rl.timer.C: // Timer expires, no response
fmt.Printf("Didn't get a response for packet %v, queueing for resend...\n", rl.packet.ID)
socketClient.packetResend <- rl.packet
responseManager.remove(rl.packet.ID)
case err := <-rl.recv: // We got a response
rl.timer.Stop() // Stop that timer
if err != nil { // Something went wrong, resend TODO: probably check to make sure this is a server-side error
fmt.Printf("Response to packet %v was an error: %v\n", rl.packet.ID, err)
fmt.Printf("Queueing packet %v for resend...\n", rl.packet.ID)
socketClient.packetResend <- rl.packet
}
responseManager.remove(rl.packet.ID)
}
}