Back

How to prevent race conditions ?

  • 0
  • Databases
  • Functions
  • Cloud
Chandan Gowda
14 Aug, 2023, 03:03

I'm using a cloud function for match making.

This is my approach:

  1. User A creates a request which will add a document into requests collection
  2. If User B with same language requests, then I am querying the requests collection to get the oldest request by any user which in this case is User A and then deleting both A and B's request
  3. Add a document in active-pairs collection

This leads to race conditions in production. Is there any better approach for the same ?

TL;DR
To prevent race conditions in a matchmaking system, you can follow these steps: 1. Implement an atomic document creation process when a user creates a matchmaking request. This ensures that the creation of the document is done without any race conditions. 2. Create a scheduled background process or cloud function that runs at regular intervals. This process will handle the matchmaking logic by identifying potential matches among the requests. 3. Within the background process, query the requests collection for potential matches based on criteria such as language. Group the requests by language and timestamp. 4. Create active-pairs documents atomically for each group of potential matches, while deleting the respective requests.
longline
14 Aug, 2023, 03:10

i only have gpt to ask would u want to read its answer

longline
14 Aug, 2023, 03:11
  1. Atomic Document Creation: When a user creates a matchmaking request, create a new document with a unique identifier that includes user information, request details, and a timestamp. This should be done atomically to avoid race conditions.
  2. Scheduled Background Process: Implement a scheduled background process or cloud function that runs at regular intervals. This process will perform the matchmaking by identifying potential matches among the requests.
  3. Matching Logic: Within the background process, query the requests collection for potential matches based on language or other criteria. Group the requests by language and then timestamp.
  4. Create Active Pairs: For each group of potential matches, create active-pairs documents atomically while deleting the respective requests. This helps prevent race conditions, as the matchmaking process is now centralized and not directly influenced by individual user actions.
  5. Expiry and Cleanup: To handle cases where requests don't find matches, implement an expiry mechanism. If a request remains unmatched for a certain period, the background process can clean up expired requests.
  6. Notification System: Implement a notification system to inform users when a match is found. This can be done via real-time messaging or email.
  7. Database Transactions: If your database supports transactions, use them for the creation of active-pairs documents and the deletion of requests. This ensures atomicity and consistency.
  8. Load Balancing: Distribute the background matchmaking process across multiple instances to handle high loads efficiently.

By moving the matchmaking process to a centralized background function, you can better control the timing of matches and avoid many race conditions associated with individual requests. This approach should help you create a more reliable and consistent matchmaking system in a production environment.

Drake
14 Aug, 2023, 03:12

The best way to prevent race conditions is with clever use of unique indexes. In short, the unique index can prevent multiple users from grabbing the same request

You might want to have a matches collection and a unique index on that.

Chandan Gowda
14 Aug, 2023, 03:15

I'm getting confused. Can you please help me with it ?

Drake
14 Aug, 2023, 03:21

Do you understand how to use a unique index to prevent race conditions?

Chandan Gowda
14 Aug, 2023, 03:33

What I understood was:

  1. User A's request is in queue (ie requests collection)
  2. User B makes a request
  3. Now I will try adding a document with the user A and B's requestDocId to matches collection which has an attribute to hold the doc id of A and B and which is unique
Chandan Gowda
14 Aug, 2023, 03:52

But in this case, if a document's userDocId1 is present in another document's userDocId2. How can I check that ?

Akshay Rana Gujjar
14 Aug, 2023, 03:56

I think you can use bool check if there is a match you can set this to true otherwise it should be false.

Chandan Gowda
14 Aug, 2023, 03:56

But i guess even that will lead to race conditions in production.

Drake
14 Aug, 2023, 04:11

The race condition you need to prevent is multiple users matching with user A

Drake
14 Aug, 2023, 04:13

So maybe have a request lock collection with the unique index. When user b creates a document in there with the user a request, they have a lock on that and will prevent others from also grabbing that request

Chandan Gowda
14 Aug, 2023, 04:16

So, is there any way to execute a cloud function in the middle of create document initiation to just before adding a document to a collection so that we can prevent another user C from getting paired with B ?

Akshay Rana Gujjar
14 Aug, 2023, 04:33

When there is already a request of user A in collection and when user B try to find the match, you can first check if there is a match present in the collection or not if present then don't create user B's request and create new document in pair match collection with both user ids along with user A request id or if match is not present then create user B's request in request collection. This way if user A and B matched then user C will not match with A or B user.

Drake
14 Aug, 2023, 04:36

A function wouldn't help with that. The requests lock collection with unique index is what I was suggesting to prevent another user C from getting the request from user B while A

Drake
14 Aug, 2023, 04:38

See my previous message

Akshay Rana Gujjar
14 Aug, 2023, 04:44

@Steven unique index on which attribute?

Chandan Gowda
14 Aug, 2023, 05:02

Checked this. But didnt actually get what you meant. :/

Chandan Gowda
14 Aug, 2023, 05:03

This is what is implemented as of now afaik

Guille
14 Aug, 2023, 12:52

Share more info about your collection, so we can help you with the Steven approach

Chandan Gowda
14 Aug, 2023, 14:54
Chandan Gowda
14 Aug, 2023, 14:54
Guille
14 Aug, 2023, 15:20

So you want to avoid the race condition in active-pairs right? can you explain the attributes in the active-pairs? what Steven said was to create a unique index, to avoid multiples values in the collection, to do that you can use for example userName1 and userDocId1 for your index. This will throw an error when this two values are stored in the collection and the function try to add it again

Chandan Gowda
14 Aug, 2023, 16:52

Thanks. I have made necessary changes. Will test it and get back to you if I have any questions.

Guille
17 Aug, 2023, 19:17

Hey @Chandan Gowda did you solve your problem?

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more