question

jngourdol avatar image
jngourdol asked

Make sure GrantItemsToUser cannot be executed twice,make GrantItemsToUser call idempotent

I need my game server to process some inventory request to remove or add inventory items to players. I also need to ensure no item can be lost or duplicated while doing so, as I'm implementing a trading system.

For removing items, there is no problem: I can call Server/RevokeInventoryItems, and since the items to revoke are identified by their ItemInstanceId, if for some weird reason I happen to call the playfab API twice (because my server failed to get the answer of the first call, or failed to persistent this result for instance), nothing wrong will happen. Previously revoked items will just stay revoked. I have no such luck with adding inventory items with Server/GrantItemsToUser though.

If a call to Server/GrantItemsToUser is made to Playfab's API twice by mistake, the item will be granted twice, effectively duplicating it. I don't have a way to specify a transaction id in the request that will ensure idempotency. My idea to ensure a transaction cannot be played twice by accident would be to input the transaction idin the only field from GrantItemsToUser that's custom, that is the Annotation field. Then I would need a CloudScript that reacts to the request and accept or reject it. Is that possible to do? Or is there a better (and possibly simpler) way to create add or remove item from inventory transactions?

,

I need my game server to process some transactions and give or remove items from users accordingly. I need to ensure that a given transaction is not played twice accidentally, because something weird happened and my server could not get Playfab's response, or had a failure when persisting the result of the call to Playfab.

I have no issue with the removing an item part: I can just use Server/RevokeInventoryItems : if for any reason I send the request twice, it will only revoke the item once because it's uniquely identified by the item's ItemInstanceId. I have no such luck with Server/GrantItemsToUser.

Is there a way to ensure I cannot accidentally replay the same transaction? Maybe by filling the Annotation field of Server/GrantItemsToUser and using it to validate in a cloud script the transaction has not been performed already?

apis
1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jngourdol avatar image jngourdol commented ·

Sorry about the duplicated question, when I first tried to post it, instead of showing it to me the website responded with "you are now logged in!". I thought I had lost the message.

0 Likes 0 ·

1 Answer

·
brendan avatar image
brendan answered

No, the problem is that the value you're trying to use as the ID would have to be written somewhere and then checked by the other instance(s) of the Cloud Script. Clearly, that cannot be done in an idempotent manner, since the calls could be happening concurrently.

The new commerce system we're working on releasing later this year does support idempotent transactions (among other improvements). I should also point out that the legacy trading system in PlayFab (https://docs.microsoft.com/en-us/rest/api/playfab/client/trading?view=playfab-rest) does prevent items from being lost or duplicated. I suspect the issue you have is that it does not support Virtual Currencies or stackable items, yes? So you know, we do plan on making an improved trading system part of the new commerce service, as well.

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jngourdol avatar image jngourdol commented ·

The legacy trading system has a lot of issues for my use case. It only support trades (item simultaneously leaving a player's inventory and entering another player's immediately) when I need distinct removal and addition (with the item being handled in between by a third party trading platform) and necessitates a user session token (unsuitable for server calls).

As you point out, Playfab data management does not allow for concurrency management either. So the solution I was envisionning does not work either. How can Playfab miss such a fundamental feature? Later this year won't do it for me, I need something now!

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.