Permalink
Cannot retrieve contributors at this time
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?
Generator-Server/responseManager.go
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
79 lines (66 sloc)
2.36 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |