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

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

Open
dyggod opened this issue Mar 6, 2025 · 3 comments
Labels
bug Something isn't working

Comments

@dyggod
Copy link

dyggod commented Mar 6, 2025

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.

@dyggod dyggod added the bug Something isn't working label Mar 6, 2025
@mikeee
Copy link
Member

mikeee commented Mar 6, 2025

What version of dapr/cli are you using?

max-body-size is the only supported option from 1.15. Can you use that and report back with the issue you're seeing?

@dyggod
Copy link
Author

dyggod commented Mar 7, 2025

What version of dapr/cli are you using?

max-body-size is the only supported option from 1.15. Can you use that and report back with the issue you're seeing?

Thanks, here is my Dapr version::

➜  Src git:(main) ✗ dapr version                            
CLI version: 1.13.0 
Runtime version: 1.13.2

And I have already set the maximum limit to exceed 4MB in the command line and in the custom-grpc-client.go code,This is my run command, :

 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

This is the error message I get when running the custom-grpc-client above:

== APP == Writing large data blob...
WARN[0001] [DEPRECATION NOTICE] InvokeService is deprecated and will be removed in the future, please use proxy mode instead.  app_id=custom-grpc-client instance=localhost.localdomain scope=dapr.runtime.grpc.api type=log ver=1.13.2
== APP == panic: rpc error: code = ResourceExhausted desc = trying to send message larger than max (41943086 vs. 4194304)
== APP == 
== APP == goroutine 1 [running]:
== APP == main.main()
== APP ==       /root/dyg/github/go-sdk/examples/service/custom-grpc-client/main.go:70 +0x83d
== APP == exit status 2

It works for SaveState, but it does not work for InvokeMethodWithContent.

So do I have to upgrade to 1.15.0?
Is there a way to do this without upgrading? My device is in an offline environment.

@dyggod
Copy link
Author

dyggod commented Mar 10, 2025

@mikeee Excuse me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants