1// 2// Freelance client - Model 1. 3// Uses REQ socket to query one or more services 4// 5 6package main 7 8import ( 9 zmq "github.com/pebbe/zmq4" 10 11 "errors" 12 "fmt" 13 "os" 14 "time" 15) 16 17const ( 18 REQUEST_TIMEOUT = 1000 * time.Millisecond 19 MAX_RETRIES = 3 // Before we abandon 20) 21 22func try_request(endpoint string, request []string) (reply []string, err error) { 23 fmt.Printf("I: trying echo service at %s...\n", endpoint) 24 client, _ := zmq.NewSocket(zmq.REQ) 25 client.Connect(endpoint) 26 27 // Send request, wait safely for reply 28 client.SendMessage(request) 29 poller := zmq.NewPoller() 30 poller.Add(client, zmq.POLLIN) 31 polled, err := poller.Poll(REQUEST_TIMEOUT) 32 reply = []string{} 33 if len(polled) == 1 { 34 reply, err = client.RecvMessage(0) 35 } else { 36 err = errors.New("Time out") 37 } 38 return 39} 40 41// The client uses a Lazy Pirate strategy if it only has one server to talk 42// to. If it has 2 or more servers to talk to, it will try each server just 43// once: 44 45func main() { 46 request := []string{"Hello world"} 47 reply := []string{} 48 var err error 49 50 endpoints := len(os.Args) - 1 51 if endpoints == 0 { 52 fmt.Printf("I: syntax: %s <endpoint> ...\n", os.Args[0]) 53 } else if endpoints == 1 { 54 // For one endpoint, we retry N times 55 for retries := 0; retries < MAX_RETRIES; retries++ { 56 endpoint := os.Args[1] 57 reply, err = try_request(endpoint, request) 58 if err == nil { 59 break // Successful 60 } 61 fmt.Printf("W: no response from %s, retrying...\n", endpoint) 62 } 63 } else { 64 // For multiple endpoints, try each at most once 65 for endpoint_nbr := 0; endpoint_nbr < endpoints; endpoint_nbr++ { 66 endpoint := os.Args[endpoint_nbr+1] 67 reply, err = try_request(endpoint, request) 68 if err == nil { 69 break // Successful 70 } 71 fmt.Println("W: no response from", endpoint) 72 } 73 } 74 if len(reply) > 0 { 75 fmt.Printf("Service is running OK: %q\n", reply) 76 } 77} 78