Skip to content

Commit 44be235

Browse files
author
Jakub Matys
committed
Added --timeout option
1 parent b875e6c commit 44be235

File tree

1 file changed

+52
-16
lines changed

1 file changed

+52
-16
lines changed

msgpack-cli.go

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"reflect"
2828
"strconv"
2929
"strings"
30+
"time"
3031
"unicode"
3132
"unicode/utf8"
3233
)
@@ -36,7 +37,7 @@ const usage = `msgpack-cli
3637
Usage:
3738
msgpack-cli encode <input-file> [--out=<output-file>]
3839
msgpack-cli decode <input-file> [--out=<output-file>] [--pp]
39-
msgpack-cli rpc <host> <port> <method> [<params>|--file=<input-file>] [--pp]
40+
msgpack-cli rpc <host> <port> <method> [<params>|--file=<input-file>] [--pp] [--timeout=<timeout>]
4041
msgpack-cli -h | --help
4142
msgpack-cli --version
4243
@@ -51,6 +52,7 @@ Options:
5152
--out=<output-file> Write output data to file instead of STDOUT
5253
--file=<input-file> File where parameters or RPC method are read from
5354
--pp Pretty-print - indent output JSON data
55+
--timeout=<timeout> Timeout of RPC call [default: 30]
5456
5557
Arguments:
5658
<input-file> File where data are read from
@@ -60,7 +62,13 @@ Arguments:
6062
<params> Parameters of RPC method in JSON format`
6163

6264
type Options struct {
63-
indent bool
65+
indent bool
66+
timeout uint32
67+
}
68+
69+
type RPCResult struct {
70+
reply interface{}
71+
err error
6472
}
6573

6674
func main() {
@@ -86,12 +94,21 @@ func main() {
8694
host := arguments["<host>"].(string)
8795
port := arguments["<port>"].(string)
8896
method := arguments["<method>"].(string)
89-
params, err := getRPCParams(arguments)
97+
var params string
98+
params, err = getRPCParams(arguments)
99+
if err != nil {
100+
break
101+
}
102+
var timeout uint32
103+
timeout, err = getTimeout(arguments)
90104
if err != nil {
91105
break
92106
}
93107

94-
options := Options{indent: arguments["--pp"].(bool)}
108+
options := Options{
109+
indent: arguments["--pp"].(bool),
110+
timeout: timeout,
111+
}
95112

96113
err = doRPC(host, port, method, params, options)
97114
default:
@@ -160,22 +177,31 @@ func doRPC(host, port, method, params string, options Options) error {
160177
}
161178
defer conn.Close()
162179

163-
var reply interface{}
164-
if reply, err = callRPC(conn, method, args); err != nil {
165-
return err
166-
}
180+
result := make(chan RPCResult)
181+
defer close(result)
167182

168-
var jsonData string
169-
if jsonData, err = encodeJSON(reply, options.indent); err != nil {
170-
return err
171-
}
183+
go callRPC(result, conn, method, args)
184+
185+
select {
186+
case res := <-result:
187+
if res.err != nil {
188+
return res.err
189+
}
172190

173-
fmt.Println(jsonData)
191+
var jsonData string
192+
if jsonData, err = encodeJSON(res.reply, options.indent); err != nil {
193+
return err
194+
}
195+
196+
fmt.Println(jsonData)
197+
case <-time.After(time.Duration(options.timeout) * time.Second):
198+
return fmt.Errorf("RPC call timed out")
199+
}
174200

175201
return nil
176202
}
177203

178-
func callRPC(conn net.Conn, method string, args interface{}) (interface{}, error) {
204+
func callRPC(result chan<- RPCResult, conn net.Conn, method string, args interface{}) {
179205
handle := getHandle()
180206
rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, &handle)
181207
client := rpc.NewClientWithCodec(rpcCodec)
@@ -184,10 +210,10 @@ func callRPC(conn net.Conn, method string, args interface{}) (interface{}, error
184210
var mArgs codec.MsgpackSpecRpcMultiArgs = args.([]interface{})
185211

186212
if err := client.Call(method, mArgs, &reply); err != nil {
187-
return nil, fmt.Errorf("RPC error: %s", err)
213+
result <- RPCResult{reply: nil, err: fmt.Errorf("RPC error: %s", err)}
188214
}
189215

190-
return reply, nil
216+
result <- RPCResult{reply: reply, err: nil}
191217
}
192218

193219
func convertJSON2Msgpack(data []byte, options Options) (result []byte, err error) {
@@ -279,3 +305,13 @@ func getRPCParams(arguments map[string]interface{}) (params string, err error) {
279305

280306
return params, nil
281307
}
308+
309+
func getTimeout(arguments map[string]interface{}) (timeout uint32, err error) {
310+
timeout = uint32(30)
311+
if str := arguments["--timeout"].(string); str != "" {
312+
var tmp uint64
313+
tmp, err = strconv.ParseUint(str, 10, 32)
314+
timeout = uint32(tmp)
315+
}
316+
return timeout, err
317+
}

0 commit comments

Comments
 (0)