Custom_fields updated simultaneous cause value to turn into array

AI-generated summary

The discussion revolves around the issue of custom fields being updated simultaneously, causing values to turn into arrays. Stefan_Brighiu_M initially thought this was a fixed bug, but is now experiencing it with multiple endpoints updating user custom fields at the same time.

He considered implementing a lock on the database until the values are saved, and fzngagan suggested a previously fixed bug as a potential solution. However, Stefan_Brighiu_M is dealing with sensitive payment data and multiple sources of calls, making it challenging to minimize the calls.

eviltrout suggested three possible solutions: adding a unique index on the custom field, using a DistributedMutex, or redesigning the table. Stefan_Brighiu_M successfully implemented the DistributedMutex solution and plans to run the calls one by one to prevent future issues. He thanked eviltrout and fzngagan for their help.

This bug seems to be fixed a while back from this post. Custom_fields simultaneous save with json becomes an array

Unfortunately, I am now dealing with simultaneous endpoints being called that update the user custom_fields at the same time, making the values set by me as :text to turn into arrays.

3 endpoints called and setting custom_field to array instead of string

Any help? This blocks my entire project right now…

Running into this problem on 2.5.0.beta7 in local development.

Is there any way I can make a lock on the db until the values are saved, in this situation?

Could this be the issue i’m facing ? Differences between transactions and locking - makandra dev

Note that when two transaction run concurrently in two threads, each thread doesn’t see the other transaction’s changes until they are committed successfully. It does however see its own changes (this is a dumbed-down explanation, reality is much more complicated).

def self.cast_custom_field(key, value, types, return_array = true)

Shows normal values, which makes me think multiple rows were created.

This should have fixed it. It was a long standing bug.

Yes I saw it :frowning:

Unfortunately I am now faced with updating sensitive data potentially at the same time. I think this happens because I am doing it via endpoints, but this is the only way I can do it and I do no have control over the calls. It can be 1 call, it can be 10.

I can try to minimize the calls from the app and bulk send some data, the problem is there are 2 sources for the calls: mobile and external services.

Payment data is involved :frowning:

This sounds like the existing behaviour of custom fields and not a regression. There are a few ways to fix it:

  1. You can add a unique index on the custom field (name, user_id)
  2. You can surround your code with a DistributedMutex
  3. You can use a table design rather than custom fields

something like this? Seems to work.

DistributedMutex.synchronize("user_data_update_#{user.id}") do
    user.save_custom_fields(true)
end

On top of this, I will change the logic to run the calls one by one instead of all at once, hopefully preventing any issues.

Thanks guys @eviltrout @fzngagan