Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toggle repository potential synchronization issue #150

Open
maorelias opened this issue Jan 3, 2022 · 8 comments
Open

Toggle repository potential synchronization issue #150

maorelias opened this issue Jan 3, 2022 · 8 comments
Assignees

Comments

@maorelias
Copy link

maorelias commented Jan 3, 2022

Maybe I'm missing something, but it seems like the periodic update of the feature toggle repository is not guaranteed to synchronize cross thread.
Here the toggle collection is reassigned in the periodic update routine, but it's not volatile and the update is not performed in the context of a lock (as far as I could see).
Since other threads (of the app) may perform read operations later, they don't seem to be guaranteed to read the latest copy of the toggles? (e.g. if the local cache of the reading thread is not invalidated).

Thanks in advance!

@ivarconr
Copy link
Member

ivarconr commented Jan 3, 2022

Hi there,

I do not see how this can be a problem? You should only instantiate a single instance of the SDK in your application. The toggle collection itself is never exposed out, and only the value or a copy if it is returned back to the calling function. The periodic fetching happens in the background on a single thread.

If you put any cache between the SDK and the function calling the SDK you will be required to invalidate that cache yourself.

@maorelias
Copy link
Author

Hi,
In the case I mentioned - the reading thread will be the app thread trying to check if some toggle is enabled (via the API) and the writing thread is the single thread executing the periodic refresh.
As far as I can see, there is no synchronization between them and so the reading thread might always be reading old copies of the toggle collection.
Am I missing something?

@ivarconr
Copy link
Member

ivarconr commented Jan 3, 2022

I really do not understand how this would be a problem?

The private member field "toggleCollection" is a shared resource between the "reading thread" and the periodic background checker. If updates are detected the pointer is swapped with the new "toggleCollection".

Synchronization in java is used to control access to "shared resources". Because swapping the pointer is a single operation, and we do not care if someone else is reading while swapping (they might get an old value in the transition), but because the pointer is changed, all reading threads will get the updated values, after the pointer is swapped.

Are you able to provide example code that demonstrates your concern and how this is not working as you would expect?

@maorelias
Copy link
Author

but because the pointer is changed, all reading threads will get the updated values, after the pointer is swapped.

Why are the reading threads guaranteed to get the updated values?
This depends on whether their (= the threads') local cache is invalidated or not, which can very between different processor architectures and applications?
I have a strong feeling that the collection needs to be declared as volatile (or some other equivalent) as to guarantee that the reading thread will always read the most recent copy?

@checketts
Copy link
Contributor

checketts commented Jan 3, 2022

I believe @maorelias Is correct. @ivarconr when different threads in java are accessing a variable that could change, there is chance that a thread could read a stale (cached) value. (By 'cached' that refers to a CPU processor cache)

I don't think there is a very large risk here, but adding volatile or using an AtomicReference would make the code more correct.

Here is a good summary on volatile and its impact on cpu/memory. (https://www.baeldung.com/java-volatile)

@ivarconr
Copy link
Member

ivarconr commented Jan 3, 2022

Thanks @checketts, I have read up on Java Threading and I think there is a potential risk here, but I assume in most cases it will correct itself fast enough in practice, and that is why this has never been brought up before.

I agree that adding volatile could be a good way to increase the read guarantees.

Anyone up for a PR?

Thanks for putting this to our attention @maorelias 👍🏼

@checketts
Copy link
Contributor

checketts commented Jan 3, 2022

Feel free to assign the issue to me. I have another PR I'll be working on soon. (Unless @maorelias wants to tackle this)

@maorelias
Copy link
Author

maorelias commented Jan 3, 2022

@checketts go ahead :) thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants