asynkron / protoactor-go

Proto Actor - Ultra fast distributed actors for Go, C# and Java/Kotlin
http://proto.actor
Apache License 2.0
4.97k stars 515 forks source link

Error when sending large message to remote actors #1114

Open iori2333 opened 1 month ago

iori2333 commented 1 month ago

Describe the bug When communicating with remote actors, messages are sent via grpc, which has limited single message extent to 4MB (4194304 bytes). Therefore, when messages are larger than 4MB (a hi-res image for instance), Proto Actor will fail sending them.

Here's outputs:

# client
3:15AM INF EndpointWriter connected lib=Proto.Actor system=VSXywC7bpefCDZRBtoED8w address=127.0.0.1:8080 cost=1.811262ms
3:15AM ERR EndpointWriter lost connection lib=Proto.Actor system=VSXywC7bpefCDZRBtoED8w address=127.0.0.1:8080 error="rpc error: code = ResourceExhausted desc = grpc: received message larger than max (10485815 vs. 4194304)"
3:15AM INF EndpointWatcher handling terminated lib=Proto.Actor system=VSXywC7bpefCDZRBtoED8w address=127.0.0.1:8080 watched=0
# server
3:15AM INF EndpointReader failed to read lib=Proto.Actor system=ng79Vwy5kszALchGm4Y3RS error="rpc error: code = ResourceExhausted desc = grpc: received message larger than max (10485815 vs. 4194304)"
3:15AM INF EndpointReader is closing lib=Proto.Actor system=ng79Vwy5kszALchGm4Y3RS

To Reproduce

system.Root.Send(server, &proto.A{ Data: generateBytes(1024 1024 10), // a very large message })



**Expected behavior**
An option to set the max message length should be provided, or the platform should support streaming messages.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.
rogeralsing commented 1 month ago

Just changing the message size limit is possible by configuring the Remote layer.

func WithDialOptions(options ...grpc.DialOption) ConfigOption {
    return func(config *Config) {
        config.DialOptions = options
    }
}

// WithServerOptions sets the server options for the remote
func WithServerOptions(options ...grpc.ServerOption) ConfigOption {
    return func(config *Config) {
        config.ServerOptions = options
    }
}

Adding streaming support to messages is problematic as we are at the mercy of gRPC itself here. to make this work we would first have to get the size of the message and then write it in chunks. This would likely severely impact overall performance.

but if someone want to give this a try, I´m flagging this as up for grabs