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