justinmclean opened a new issue, #9084:
URL: https://github.com/apache/gravitino/issues/9084

   ### What would you like to be improved?
   
   The loadRole method (in 
core/src/main/java/org/apache/gravitino/authorization/AuthorizationRequestContext.java)
  isn’t thread-safe as it has a race condition. Because hasLoadRole.get() and 
hasLoadRole.set(true) are separate operations, multiple threads can see false 
and run the runnable simultaneously.
   
   Suppose two threads call loadRole() at roughly the same time: 
   - Both check hasLoadRole.get() before it’s set and both see false.
   - Both enter the if body and run runnable.run().
   - Then both set hasLoadRole.set(true) afterward.
   
   So you can end up with double (or more) executions of the runnable.
   
   Here's a unit test to illustrate:
   ```
   @Test
     public void testLoadRoleRunsOnceEvenWhenInvokedConcurrently() throws 
Exception {
       AuthorizationRequestContext context = new AuthorizationRequestContext();
       AtomicInteger counter = new AtomicInteger();
       CountDownLatch firstStarted = new CountDownLatch(1);
       CountDownLatch allowFinish = new CountDownLatch(1);
   
       Thread firstInvocation =
           new Thread(
               () ->
                   context.loadRole(
                       () -> {
                         counter.incrementAndGet();
                         firstStarted.countDown();
                         try {
                           allowFinish.await(5, TimeUnit.SECONDS);
                         } catch (InterruptedException e) {
                           Thread.currentThread().interrupt();
                         }
                       }));
       firstInvocation.start();
   
       try {
         assertTrue(firstStarted.await(5, TimeUnit.SECONDS));
         context.loadRole(() -> counter.incrementAndGet());
         assertEquals(1, counter.get(), "loadRole should execute runnable only 
once");
       } finally {
         allowFinish.countDown();
         firstInvocation.join();
       }
   
       context.loadRole(() -> counter.incrementAndGet());
       assertEquals(1, counter.get(), "Subsequent loadRole calls should be 
ignored");
     }
   ```
   
   ### How should we improve?
   
   AtomicBoolean makes single operations thread-safe, but not combinations of 
them, use compareAndSet() instead.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to