Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RequestTimeout is not respected when API is called with context #46

Open
adriantam opened this issue Jun 8, 2023 · 5 comments
Open

Comments

@adriantam
Copy link

adriantam commented Jun 8, 2023

We have set the RequestTimeout to 75ms in our DAX client. However, when TCP connection is re-establshed, we still see some DAX request in the 6s range (which based on our discussion with AWS team are caused by connection being re-established).

Looking at the Go SDK, it appears that the issue is due to SDK not respecting the request timeout if it is called with context.

See

if ctx == nil && c.RequestTimeout > 0 {

Please note that we use QueryWithContext as per https://pkg.go.dev/github.com/zabawaba99/aws-dax-go/dax#Dax.QueryWithContext.

@anudeeb
Copy link

anudeeb commented Jun 9, 2023

Are you setting timeouts in the context that's passed to DAX SDK? If you are explicitly passing in a context, it should look like below if you want to configure 50 ms timeout:

ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)  

client.GetItemWithContext(ctxTimeout, in)

When context is passed to the SDK, we will honour the timeout that's set in the context and will not consider the RequestTimeout field value which was set during client initialisation.

That's why in the below code, the request timeout is overridden if context is provided -

if ctx == nil && c.RequestTimeout > 0 {

I executed couple of tests to validate this behaviour and it works as expected:

  1. I set the RequestTimeout configuration as 10 ms and while calling GetItemWithContext I provided context.Background() (infinite timeout)

    • There were no timeouts and we would see high latencies (note: simulated high server-side latencies by manually adding sleep on server-side)
    • image
  2. I set the RequestTimeout configuration as 5 seconds and while calling GetItemWithContext, passed in context with 50 ms as timeout - context.WithTimeout(context.Background(), time.Millisecond*50)

    • I saw that client-side latencies were capped at 50 ms
    • image

@adriantam
Copy link
Author

adriantam commented Jun 9, 2023

Are you setting timeouts in the context that's passed to DAX SDK? If you are explicitly passing in a context, it should look like below if you want to configure 50 ms timeout:

ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)  

client.GetItemWithContext(ctxTimeout, in)

When context is passed to the SDK, we will honour the timeout that's set in the context and will not consider the RequestTimeout field value which was set during client initialisation.

That's why in the below code, the request timeout is overridden if context is provided -

if ctx == nil && c.RequestTimeout > 0 {

I executed couple of tests to validate this behaviour and it works as expected:

  1. I set the RequestTimeout configuration as 10 ms and while calling GetItemWithContext I provided context.Background() (infinite timeout)

    • There were no timeouts and we would see high latencies (note: simulated high server-side latencies by manually adding sleep on server-side)
    • image
  2. I set the RequestTimeout configuration as 5 seconds and while calling GetItemWithContext, passed in context with 50 ms as timeout - context.WithTimeout(context.Background(), time.Millisecond*50)

    • I saw that client-side latencies were capped at 50 ms
    • image

We did not set the timeout in the context that we passed into the QueryWithContext request.

When we call the API, we do something like

	cfg := dax.DefaultConfig()
        cfg.RequestTimeout = 75 * time.Millisecond
        client, err := dax.New(cfg)
        ...
        ctx := context.Background()
        // some code to add in our own context info
        output, err := client.QueryWithContext(ctx, input, opts)

There was nothing in the documentation to suggest that Config's RequestTimeout (i.e.,

RequestTimeout time.Duration
) will only be used if there is no context provided.

@jon-whit
Copy link

jon-whit commented Jun 9, 2023

Why have the RequestTimeout config if the context dominates, especially if context.Background() overrides the top-level config setting?

Perhaps I may suggest that RequestTimeout is just dropped altogether in favor of the more idiomatic Go style of providing solely the context with timeout.

@anudeeb
Copy link

anudeeb commented Jun 13, 2023

Thank you for the feedback! We'll update the documentation in the next release to call out that the top-level configs are not honoured if the context is set.

Perhaps I may suggest that RequestTimeout is just dropped altogether in favor of the more idiomatic Go style of providing solely the context with timeout.

That's a good suggestion but unfortunately if we make that change now, the change will be backwards incompatible.

@jon-whit
Copy link

That's a good suggestion but unfortunately if we make that change now, the change will be backwards incompatible.

@anudeeb looking forward to github.com/aws/aws-dax-go/v2 😄 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants