protoactor-go
protoactor-go copied to clipboard
Consider make RequestFuture more elegent?
Is your feature request related to a problem? Please describe. I`m using protoactor-go for our project.
But I found We can make RequestFuture more elegant. consider this code snippet
// request
roomPidRes, err := System.Root.RequestFuture(roomMgrPid, info, 1*time.Second).Result()
// respond
context.Respond(&FooRoomPid)
err`s type is only time out error. I think we have a chance to reuse it. Describe the solution you'd like We can Define a response struct
type struct Response {
RetValue interface{}
Err error
}
When we use Response struct as a response value. Requester won't wait until timeOut, and when err occurred Requester will know exactly what happened.
> err's type is only time out error.
Nope, some errors defined in remote/errors.go
and actor/future.go
.
> when err occurred Requester will know exactly what happened.
Sure, I agree with you. We can just use error
which is a built-in interface type in Go.
> We can Define a response struct
Do you mean a struct wrapper of Response
and Error
?
It looks like the Optional
in Java or Option
in rust.
That's cool, but it's not zero-cost abstract
in Go, and doesn't follow the default Go style right now. Maybe Go will make a change in the future or maybe not.
> When we use Response struct as a response value. Requester won't wait until timeOut
Response struct
isn't necessary with that case.
For example:
The ErrTimeout
is meant that no response in a certain amount of time.
The ErrDeadLetter
is meant that you request to a unreachable actor.
...
The ErrBlahblah
is meant that blahblah...
...
So we can define a lot errors with different cases.
> Do you mean a struct wrapper of Response and Error?
Yes! But not like Option in rust. Request won't receive a wrapped Response. It should work in this way。
- Requester send a request
// request
res:= System.Root.RequestFuture(roomMgrPid, info, 1*time.Second)
- responser return Response
// respond
resp := &Response{
Err: fooErr
RetVAlue: fooRetValue
}
context.Respond(resp)
- requester call result()
// fooRetValue is resp.fooRetValue fooErr may be protoactor-go`s error type or resp.fooErr
fooRetValue, fooErr := res.Result()
> Response struct isn't necessary with that case.
Yes! we can use type switch to distinguish error and return value. But personally I like protoactor-go help me do this so we can.
// fooRetValue is resp.fooRetValue fooErr may be protoactor-go`s error type or resp.fooErr
fooRetValue, fooErr := res.Result()
if fooErr != nil {
// Log this error
}
// do something normal
I'm all for investigating this further. There are also an opportunity to make this Generic if needed
I also encountered this problem when I ported pubsub from csharp. Check out how I implemented a future-like structure at that time.
https://github.com/asynkron/protoactor-go/blob/8801eff88ab0fc0a6f6948f01c9846ddfbf8b299/cluster/pubsub_producer.go#L120-L146
The logic to wait for the completion of future and determine if there are any errors is like this ⬇️
https://github.com/asynkron/protoactor-go/blob/8801eff88ab0fc0a6f6948f01c9846ddfbf8b299/cluster/pubsub_producer_test.go#L85-L88
May be helpful for the design of future.