Is it a possible abnormal situation where a client makes a single custom rpc call that arrives and is called twice on the Nakama server?

Hello Heroic Labs,

I’ve had an error caused by the server receiving a second identical copy of a remote procedure call. The server had received the first copy moments before from the same client (the call is to edit group metadata fwiw). I’m reasonably confident I didn’t make an identical call to the Client API twice, because I assign incrementing ids to the call params just as I call client.rpc_async, and the ids of the duplicate calls were the same.

Is it possible under abnormal network conditions for an rpc to arrive twice? Or does the server screen for that before the rpc is called on the server?

It’s not a big problem if it is possible, I can screen calls as they come in. I just need to know if I should do that, or if I need to look elsewhere for what went wrong.

Thanks, Matt

Depending on the SDK, we could retry the request on 500 errors. For instance in the Unity SDK, we have RetryConfiguration that you can setup.

Additionally, depending on how you’ve configured your loadbalancer, this could be a property of the loadbalancer settings to auto-retry on some conditions.

Thanks very much for the answer. (I’m using Godot, and don’t have anything configured beyond the defaults.) Just to be very clear then, you’re saying the answer is yes, under certain, odd, conditions it is possible for a single rpc that was sent once by a client to be called on the server twice? Implying that if my client calls, for example,

var r:NakamaAPI.ApiRpc = await client.rpc_async(session, “rpcAChessMove”, “{‘bishop’:‘d6’}”)

that rpcAChessMove on the server needs to handle the small possibility it will be called more than once as a result, instead of concluding (as I had been) that there must necessarily be either an error in my client code or a client trying to cheat?

@MattW I think that @mofirouz was just implying that our SDKs have automatic retry on some HTTP error status ranges, but I don’t see how a successful request would trigger this behavior unless there’s incorrect logic in your custom code that would return an error status code after success (or partial success) of some of the operations.