Fix method is not safely accessed by multiple concurrent threads. - #13725
Fix method is not safely accessed by multiple concurrent threads.#13725shibd wants to merge 1 commit into
Conversation
|
@Jason918 @Technoboy- @merlimat Can you help me review it? Thanks. |
|
/pulsarbot run-failure-checks |
|
Sorry, I am not getting this yet. In the error part. We have the following key code line executed in the order: Is this the right executing order that [3] happens before [5]? |
@Jason918 Your description is only the execution order of However, there is another thread in refresh during actual operation( I use |
I saw the explanation above and sorry that I missed the key info about "Cache#invalidate", it can't invalid loading keys. This is the root cause. I think the async loading is ok if the |
|
About the solution, I still have some concerns. In my understanding, the |
|
Checked codes, we can fix this by wrap You can check |
You are right. I will solve it according to this idea and resubmit the PR. |
Motivation
#13663 Flaky-test: org.apache.pulsar.metadata.LockManagerTest.updateValue
The root cause it that
MetadataCacheImpl#refreshmethod is not safely accessed by multiple concurrent threads.pulsar/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/cache/impl/MetadataCacheImpl.java
Lines 262 to 269 in 2a7515f
The
AbstractMetadaStore.putmethod will have two threadsrefreshthe cache in parallel.(
thread 1)Callback method ofstorePutreturned:pulsar/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/AbstractMetadataStore.java
Lines 279 to 281 in 2a7515f
(
thread 2)Notification implement instorePutinternal(ZK, RocksDB, LocalMemory):pulsar/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/AbstractMetadataStore.java
Lines 183 to 193 in 2a7515f
We can only get the execution result of thread 1 on the client, and can't wait for thread 2.
When thread 2 has not finished refreshing the last time, At this point, if the update starts again, the old value may be returned. Reference by
caffeinenoteLoadingCache#refresh
Cache#invalidate
In this unit test, the first execution of the following method will trigger the update cache, and thread 2 may not complete the update all the time.
pulsar/pulsar-metadata/src/test/java/org/apache/pulsar/metadata/LockManagerTest.java
Lines 142 to 144 in 2a7515f
When the value is updated again, it is possible that the cache update did not succeed.So you may get the last cached value.
May be getValue is equals "locak-1"
pulsar/pulsar-metadata/src/test/java/org/apache/pulsar/metadata/LockManagerTest.java
Lines 146 to 148 in 2a7515f
I solved it directly with synchronous lock. After many tests, the problem no longer appears. If there is a better implementation, it can be discussed. Thank you~
Modifications
MetadataCacheImpl#refresh、MetadataCacheImpl#invalidate、MetadataCacheImpl#invalidateAllDocumentation
no-need-doc