dapr / dapr/go-sdk

The --dapr-http-max-request-size flag does not work in InvokeMethodWithContent.

Open
#707 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
479
Forks
187
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**

I am using the `examples/service/custom-grpc-client` example, and it seems to work fine with `client.SaveState`. However, when I use `InvokeMethodWithContent` to send data larger than 4MB, I still get the error: panic: rpc error: code = ResourceExhausted desc = grpc: received message larger than max (41943086 vs. 4194304). I would like to resolve this issue so that `InvokeMethodWithContent` can send and receive data exceeding 4MB. By the way, the readme suggests using `--max-body-size`, but it does not seem to be effective.

Below is my modified `custom-grpc-client.go`:
```
/*
Copyright 2021 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
    "context"
    "fmt"
    "net"
    "os"
    "time"

    "google.golang.org/grpc"

    dapr "github.com/dapr/go-sdk/client"
)

func GetEnvValue(key, fallback string) string {
    if value, ok := os.LookupEnv(key); ok {
        return value
    }
    return fallback
}

func main() {
    // Testing 40 MB data exchange
    maxRequestBodySize := 40
    // max2 := 40
    var opts []grpc.CallOption

    // Receive 40 MB + 1 MB (data + headers overhead) exchange
    headerBuffer := 1
    opts = append(opts, grpc.MaxCallRecvMsgSize((maxRequestBodySize+headerBuffer)*1024*1024))
    conn, err := grpc.Dial(net.JoinHostPort("127.0.0.1",
        GetEnvValue("DAPR_GRPC_PORT", "50001")),
        grpc.WithDefaultCallOptions(opts...), grpc.WithInsecure())
    if err != nil {
        panic(err)
    }

    // Instantiate DAPR client with custom-grpc-client gRPC connection
    client := dapr.NewClientWithConnection(conn)
    defer client.Close()

    ctx := context.Background()
    start := time.Now()

    fmt.Println("Writing large data blob...")
    data := make([]byte, maxRequestBodySize*1024*1024)
    store := "statestore" // defined in the component YAML
    key := "my_key"

    // This is my code:
    content := &dapr.DataContent{
        ContentType: "application/octet-stream",
        Data:        data,
    }
    resp, err := client.InvokeMethodWithContent(ctx, "serving", "echo", "post", content)
    if err != nil {
        panic(err)
    }
    fmt.Printf("service method invoked, response length: %d bytes\n", len(resp))

    // save state with the key my_key, default options: strong, last-write
    if err := client.SaveState(ctx, store, key, data, nil); err != nil {
        panic(err)
    }
    fmt.Println("Saved the large data blob...")
    elapsed := time.Since(start)
    fmt.Printf("Writing to statestore took %s", elapsed)

    // get state for key my_key
    fmt.Println("Getting data from the large data blob...")
    _, err = client.GetState(ctx, store, key, nil)
    if err != nil {
        panic(err)
    }
    elapsed2 := time.Since(start)
    fmt.Printf("Reading from statestore took %s\n", elapsed2)

    // delete state for key my_key
    if err := client.DeleteState(ctx, store, key, nil); err != nil {
        panic(err)
    }
    elapsed3 := time.Since(start)
    fmt.Printf("Deleting key from statestore took %s\n", elapsed3)

    fmt.Println("DONE (CTRL+C to Exit)")
}

```

I use `dapr run --app-id custom-grpc-client \
                 -d ./config \
                 --dapr-http-max-request-size 80 \
                 --log-level warn \
                 go run ./custom-grpc-client/main.go` to run it

**To Reproduce**

**Expected behavior**

I hope to be able to send and receive larger data using InvokeMethodWithContent.

Contributor guide

Open the contributing guide

Research direction

Start with examples/service/custom-grpc-client/custom-grpc-client.go and reproduce the failure using the documented dapr run command with --dapr-http-max-request-size. Trace InvokeMethodWithContent and its gRPC connection or message-size handling, comparing it with the working SaveState path. Done means requests and responses larger than 4 MB succeed through InvokeMethodWithContent without the ResourceExhausted error.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, grpc
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.