I would like a gRPC server, written in Go, to be able to implement something like the following. My question is whether the "good thing" happens enough to provide a benefit. It is fine if sometimes the "good thing" does not happen.
The server is receiving updates from a large number of clients by an RPC, say "Update", and then forward each on one to a third agent. The forwarding-on is normally speedy, but might fail or be slow because it's just another RPC to a different system. Each update has an id which guarantees idempotency, so duplicated updates are not an issue, but lost ones must be prevented. I would like to have the return from "Update" imply "I have taken possession of the update; it is or will be forwarded on", resulting in a trivial server stub which does this: return msg.Forward(ctx) This is fine and clearly correct; the if the Update RPC is canceled the error will indicate to the client that it cannot assume the update is or will be forwarded, and can retry appropriately. But it would be nice to avoid that retry in the commonest case, which is simply that forwarding on took too long for some reason, but everything else is good. In that situation, I would like my server to notice that the Forward call was canceled, persist the update to disk, and then return success from the Update stub. I want that successful return to be propagated back to the client. (This is the "good thing.") This would be: err := msg.Forward(ctx) if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { msg.PersistToDisk() return true } return err If the success is occasionally not delivered to the client, that's fine; at least we tried to avoid the unnecessary retry. But if it's never delivered back, then there's no point in doing the persistence - the client will just always retry and so it doesn't matter. And we don't want to just write every update to disk, because in the normal case Forward proceeds quickly and there's no need to stick another I/O bottleneck in the way on the most common fast path. So will the "good thing" happen, at least often? That is: if a Go gRPC server stub is canceled, and the stub implementation handles the context cancelation by returning success, will that (at least often) be reflected back to the RPC client? [Note that in a non-gRPC context, in which these are just all local function calls, the answer is defined by the Go Language Specification - the return value is of course returned no matter what the state of the context may be.] Thomas -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/de635afa0e28433cafa6c60ba0c10b80%40deshaw.com.