Skip to content

Commit 7c38f5a

Browse files
authored
fix: client default timeout (dapr#310)
* fix: client default timeout dapr#259 Signed-off-by: Ceres Cheng <chengzhoukun@gmail.com> * Add documentation for client timeout environment variable Signed-off-by: Ceres Cheng <chengzhoukun@gmail.com>
1 parent c4217cf commit 7c38f5a

File tree

3 files changed

+88
-10
lines changed

3 files changed

+88
-10
lines changed

Readme.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@ func main() {
3636
}
3737
```
3838

39+
`NewClient` function has a default timeout for 5s, but you can customize this timeout by setting the environment variable `DAPR_CLIENT_TIMEOUT_SECONDS`.
40+
For example:
41+
```go
42+
package main
43+
44+
import (
45+
"os"
46+
47+
dapr "github.com/dapr/go-sdk/client"
48+
)
49+
50+
func main() {
51+
os.Setenv("DAPR_CLIENT_TIMEOUT_SECONDS", "3")
52+
client, err := dapr.NewClient()
53+
if err != nil {
54+
panic(err)
55+
}
56+
defer client.Close()
57+
}
58+
```
59+
3960
Assuming you have [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr/) installed, you can then launch your app locally like this:
4061

4162
```shell

client/client.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"log"
2020
"net"
2121
"os"
22+
"strconv"
2223
"sync"
2324
"time"
2425

@@ -38,11 +39,13 @@ import (
3839
)
3940

4041
const (
41-
daprPortDefault = "50001"
42-
daprPortEnvVarName = "DAPR_GRPC_PORT" /* #nosec */
43-
traceparentKey = "traceparent"
44-
apiTokenKey = "dapr-api-token" /* #nosec */
45-
apiTokenEnvVarName = "DAPR_API_TOKEN" /* #nosec */
42+
daprPortDefault = "50001"
43+
daprPortEnvVarName = "DAPR_GRPC_PORT" /* #nosec */
44+
traceparentKey = "traceparent"
45+
apiTokenKey = "dapr-api-token" /* #nosec */
46+
apiTokenEnvVarName = "DAPR_API_TOKEN" /* #nosec */
47+
clientDefaultTimoutSeconds = 5
48+
clientTimoutSecondsEnvVarName = "DAPR_CLIENT_TIMEOUT_SECONDS"
4649
)
4750

4851
var (
@@ -182,10 +185,11 @@ type Client interface {
182185
// Note, this default factory function creates Dapr client only once. All subsequent invocations
183186
// will return the already created instance. To create multiple instances of the Dapr client,
184187
// use one of the parameterized factory functions:
185-
// NewClientWithPort(port string) (client Client, err error)
186-
// NewClientWithAddress(address string) (client Client, err error)
187-
// NewClientWithConnection(conn *grpc.ClientConn) Client
188-
// NewClientWithSocket(socket string) (client Client, err error)
188+
//
189+
// NewClientWithPort(port string) (client Client, err error)
190+
// NewClientWithAddress(address string) (client Client, err error)
191+
// NewClientWithConnection(conn *grpc.ClientConn) Client
192+
// NewClientWithSocket(socket string) (client Client, err error)
189193
func NewClient() (client Client, err error) {
190194
port := os.Getenv(daprPortEnvVarName)
191195
if port == "" {
@@ -216,7 +220,11 @@ func NewClientWithAddress(address string) (client Client, err error) {
216220
}
217221
logger.Printf("dapr client initializing for: %s", address)
218222

219-
ctx, ctxCancel := context.WithTimeout(context.Background(), 1*time.Second)
223+
timeoutSeconds, err := getClientTimeoutSeconds()
224+
if err != nil {
225+
return nil, err
226+
}
227+
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Duration(timeoutSeconds)*time.Second)
220228
conn, err := grpc.DialContext(
221229
ctx,
222230
address,
@@ -234,6 +242,21 @@ func NewClientWithAddress(address string) (client Client, err error) {
234242
return newClientWithConnectionAndCancelFunc(conn, ctxCancel), nil
235243
}
236244

245+
func getClientTimeoutSeconds() (int, error) {
246+
timeoutStr := os.Getenv(clientTimoutSecondsEnvVarName)
247+
if len(timeoutStr) == 0 {
248+
return clientDefaultTimoutSeconds, nil
249+
}
250+
timeoutVar, err := strconv.Atoi(timeoutStr)
251+
if err != nil {
252+
return 0, err
253+
}
254+
if timeoutVar <= 0 {
255+
return 0, errors.New("incorrect value")
256+
}
257+
return timeoutVar, nil
258+
}
259+
237260
// NewClientWithSocket instantiates Dapr using specific socket.
238261
func NewClientWithSocket(socket string) (client Client, err error) {
239262
if socket == "" {

client/client_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,40 @@ func getTestClientWithSocket(ctx context.Context) (client Client, closer func())
196196
return
197197
}
198198

199+
func Test_getClientTimeoutSeconds(t *testing.T) {
200+
t.Run("empty env var", func(t *testing.T) {
201+
os.Setenv(clientTimoutSecondsEnvVarName, "")
202+
got, err := getClientTimeoutSeconds()
203+
assert.NoError(t, err)
204+
assert.Equal(t, clientDefaultTimoutSeconds, got)
205+
})
206+
207+
t.Run("invalid env var", func(t *testing.T) {
208+
os.Setenv(clientTimoutSecondsEnvVarName, "invalid")
209+
_, err := getClientTimeoutSeconds()
210+
assert.Error(t, err)
211+
})
212+
213+
t.Run("normal env var", func(t *testing.T) {
214+
os.Setenv(clientTimoutSecondsEnvVarName, "7")
215+
got, err := getClientTimeoutSeconds()
216+
assert.NoError(t, err)
217+
assert.Equal(t, 7, got)
218+
})
219+
220+
t.Run("zero env var", func(t *testing.T) {
221+
os.Setenv(clientTimoutSecondsEnvVarName, "0")
222+
_, err := getClientTimeoutSeconds()
223+
assert.Error(t, err)
224+
})
225+
226+
t.Run("negative env var", func(t *testing.T) {
227+
os.Setenv(clientTimoutSecondsEnvVarName, "-3")
228+
_, err := getClientTimeoutSeconds()
229+
assert.Error(t, err)
230+
})
231+
}
232+
199233
type testDaprServer struct {
200234
pb.UnimplementedDaprServer
201235
state map[string][]byte

0 commit comments

Comments
 (0)