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

Refactor Busy-Waiting Loops to Improve Efficiency #3123

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Mostafa-Hisham0
Copy link

@Mostafa-Hisham0 Mostafa-Hisham0 commented Dec 7, 2024

What problem does this PR solve?

This PR refactors the busy-waiting loops in the following files:

  • Server Session / App.java
  • Twin / BallThread.java
  • Log Aggregation / LogAggregator.java
  • Commander / Retry.java
  • Retry / Retry.java
  • Retry / RetryExponentialBackoff.java
  • Queue-Based Load Leveling / ServiceExecutor.java

…ation

- Replaced busy-waiting loops with appropriate synchronization mechanisms across multiple files.
- Improved thread management in `BallThread.java`, `Retry.java`, `RetryExponentialBackoff.java`, and `ServiceExecutor.java`.
- Introduced exponential backoff for retry logic in `Retry` and `RetryExponentialBackoff`.
- Optimized queue message processing in `ServiceExecutor.java` with better sleep intervals.
- Ensured the correctness of functionality through extensive testing.
Copy link
Owner

@iluwatar iluwatar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build is failing

Copy link

github-actions bot commented Jan 14, 2025

PR Summary

This PR refactors busy-waiting loops in several Java files to improve efficiency and resource utilization. It replaces busy-waiting with synchronization mechanisms, optimizes thread management, introduces exponential backoff for retries, and enhances queue message processing. The changes improve resource utilization and responsiveness.

Changes

File Summary
commander/src/main/java/com/iluwatar/commander/Retry.java Refactored the Retry class to use ScheduledExecutorService for scheduling retries with exponential backoff, eliminating busy-waiting. This enhances efficiency and responsiveness.
microservices-log-aggregation/src/main/java/com/iluwatar/logaggregation/LogAggregator.java Improved the LogAggregator by using wait/notify mechanism to avoid busy-waiting while checking for log entries in the buffer. This makes the log aggregation more efficient.
queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/MessageQueue.java Added a serviceExecutorWait object to the MessageQueue class for synchronization, enabling the ServiceExecutor to wait efficiently for messages.
queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/ServiceExecutor.java Modified ServiceExecutor to use wait/notify mechanism instead of busy-waiting, improving efficiency in message processing. It now waits on the MessageQueue's serviceExecutorWait object.
queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/TaskGenerator.java Minor changes to logging and message submission in TaskGenerator. No significant impact on efficiency.
queue-based-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java Added new tests for ServiceExecutor start and wake states, verifying that it waits efficiently for messages and resumes when notified.
retry/src/main/java/com/iluwatar/retry/Retry.java Refactored Retry class to use ScheduledExecutorService for retry scheduling, replacing busy-waiting with efficient scheduling. Improves performance and resource usage.
retry/src/main/java/com/iluwatar/retry/RetryExponentialBackoff.java Refactored RetryExponentialBackoff to use ScheduledExecutorService for scheduling retries, removing busy-waiting. Improves efficiency and responsiveness.
server-session/src/main/java/com/iluwatar/sessionserver/App.java Improved session expiration handling in App using wait/notify mechanism to avoid busy-waiting. Added a sessionExpirationWait object for synchronization and a expirationTaskWake method to wake up the expiration task when a login request is received.
server-session/src/main/java/com/iluwatar/sessionserver/LoginHandler.java Added a comment to clarify the purpose of the LoginHandler class and added a call to App.expirationTaskWake() to notify the session expiration task when a new login occurs.
server-session/src/main/java/com/iluwatar/sessionserver/LogoutHandler.java Added a comment to clarify the purpose of the LogoutHandler class. No functional changes.
server-session/src/test/java/com.iluwatar.sessionserver/AppTest.java New test file added to verify the behavior of the session expiration task, checking its initial waiting state and its transition to a sleeping state after being woken up.
twin/src/main/java/com/iluwatar/twin/BallThread.java Refactored BallThread to use wait() and notifyAll() for suspending and resuming, eliminating busy-waiting. Improved thread management and synchronization.
twin/src/test/java/com/iluwatar/twin/BallThreadTest.java Added tests to verify the BallThread's suspend and resume functionality, confirming that the thread transitions to the WAITING state when suspended and RUNNABLE when resumed.

autogenerated by presubmit.ai

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Pull request needs attention.

Review Summary

Commits Considered (3)
  • d5864d9: updated

  • 8aa0647: Merge branch 'iluwatar:master' into master

  • 86efd3c: Refactor busy-waiting loops to improve efficiency and resource utilization

  • Replaced busy-waiting loops with appropriate synchronization mechanisms across multiple files.

  • Improved thread management in BallThread.java, Retry.java, RetryExponentialBackoff.java, and ServiceExecutor.java.

  • Introduced exponential backoff for retry logic in Retry and RetryExponentialBackoff.

  • Optimized queue message processing in ServiceExecutor.java with better sleep intervals.

  • Ensured the correctness of functionality through extensive testing.

Files Processed (14)
  • commander/src/main/java/com/iluwatar/commander/Retry.java (1 hunk)
  • microservices-log-aggregation/src/main/java/com/iluwatar/logaggregation/LogAggregator.java (4 hunks)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/MessageQueue.java (2 hunks)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/ServiceExecutor.java (2 hunks)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/TaskGenerator.java (1 hunk)
  • queue-based-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java (2 hunks)
  • retry/src/main/java/com/iluwatar/retry/Retry.java (1 hunk)
  • retry/src/main/java/com/iluwatar/retry/RetryExponentialBackoff.java (1 hunk)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java (5 hunks)
  • server-session/src/main/java/com/iluwatar/sessionserver/LoginHandler.java (2 hunks)
  • server-session/src/main/java/com/iluwatar/sessionserver/LogoutHandler.java (1 hunk)
  • server-session/src/test/java/com.iluwatar.sessionserver/AppTest.java (1 hunk)
  • twin/src/main/java/com/iluwatar/twin/BallThread.java (1 hunk)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java (4 hunks)
Actionable Comments (4)
  • retry/src/main/java/com/iluwatar/retry/Retry.java [71-71]

    performance: "Improve retry mechanism efficiency."

  • twin/src/main/java/com/iluwatar/twin/BallThread.java [53-62]

    possible bug: "Potential race condition in thread synchronization."

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [98-100]

    performance: "Improve session expiration mechanism efficiency."

  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/ServiceExecutor.java [52-54]

    possible bug: "Potential race condition in thread synchronization."

Skipped Comments (1)
  • microservices-log-aggregation/src/main/java/com/iluwatar/logaggregation/LogAggregator.java [80-81]

    possible issue: "Add error handling to log collection."

} while (true);
}
}
executorService.schedule(() -> {}, this.delay, TimeUnit.MILLISECONDS); // Schedule retry without blocking

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Thread.sleep() for delays in Retry and RetryExponentialBackoff classes is inefficient and can lead to resource wastage. Consider using ScheduledExecutorService for scheduling retries with precise delays without blocking the main thread.

Comment on lines +53 to 62
if (isSuspended) {
synchronized (lock) {
lock.wait();
}
} else {
twin.draw();
twin.move();
Thread.sleep(250);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In BallThread, the busy-waiting loop is replaced with a more efficient approach using lock.wait() and lock.notifyAll(). However, ensure that the lock object is properly synchronized to prevent race conditions.

Comment on lines 98 to 100
LOGGER.info("Session expiration checker started...");
Thread.sleep(SESSION_EXPIRATION_TIME); // Sleep for expiration time
Instant currentTime = Instant.now();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sessionExpirationTask in App.java uses busy-waiting to check for session expiration. This is inefficient. Consider using a ScheduledExecutorService to schedule the expiration check periodically without busy-waiting.

Comment on lines +52 to +54
synchronized (msgQueue.serviceExecutorWait) {
msgQueue.serviceExecutorWait.wait();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ServiceExecutor, the busy-waiting loop is replaced with msgQueue.serviceExecutorWait.wait(). Ensure that the msgQueue.serviceExecutorWait object is properly synchronized to prevent race conditions.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Pull request needs attention.

Review Summary

Commits Considered (1)
  • 0d0bb7a: Merge branch 'master' into master
Files Processed (11)
  • microservices-log-aggregation/src/main/java/com/iluwatar/logaggregation/LogAggregator.java (4 hunks)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/MessageQueue.java (2 hunks)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/ServiceExecutor.java (2 hunks)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/TaskGenerator.java (1 hunk)
  • queue-based-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java (2 hunks)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java (5 hunks)
  • server-session/src/main/java/com/iluwatar/sessionserver/LoginHandler.java (2 hunks)
  • server-session/src/main/java/com/iluwatar/sessionserver/LogoutHandler.java (1 hunk)
  • server-session/src/test/java/com.iluwatar.sessionserver/AppTest.java (1 hunk)
  • twin/src/main/java/com/iluwatar/twin/BallThread.java (1 hunk)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java (4 hunks)
Actionable Comments (4)
  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/MessageQueue.java [39-39]

    possible bug: "Potential race condition in MessageQueue."

  • queue-based-load-leveling/src/main/java/com/iluwatar/queue/load/leveling/ServiceExecutor.java [52-54]

    possible bug: "Potential issue with spurious wakeups in ServiceExecutor."

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [62-62]

    possible bug: "Potential race condition in App."

  • twin/src/main/java/com/iluwatar/twin/BallThread.java [45-45]

    possible bug: "Potential race condition in BallThread."

Skipped Comments (2)
  • microservices-log-aggregation/src/main/java/com/iluwatar/logaggregation/LogAggregator.java [131-134]

    performance: "Potential performance issue in bufferWake function."

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [91-97]

    performance: "Potential performance issue in sessionExpirationTask."

@@ -36,6 +36,7 @@
public class MessageQueue {

private final BlockingQueue<Message> blkQueue;
public final Object serviceExecutorWait = new Object();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In MessageQueue, ensure that serviceExecutorWait is properly synchronized to prevent race conditions when multiple threads access it concurrently.

Comment on lines +52 to +54
synchronized (msgQueue.serviceExecutorWait) {
msgQueue.serviceExecutorWait.wait();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wait() call in ServiceExecutor should ideally be within a loop to handle spurious wakeups. This ensures the thread waits until a message is available.

private static Map<String, Integer> sessions = new HashMap<>();
private static Map<String, Instant> sessionCreationTimes = new HashMap<>();
private static final long SESSION_EXPIRATION_TIME = 10000;
private static Object sessionExpirationWait = new Object(); // used to make expiration task wait or work based on event (login request sent or not)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In App.java, ensure that sessionExpirationWait is properly synchronized to prevent race conditions when multiple threads access it concurrently.

@@ -42,37 +42,58 @@ public class BallThread extends Thread {

private volatile boolean isRunning = true;

private final Object lock = new Object();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In BallThread, ensure that the lock object is properly synchronized to prevent race conditions when multiple threads access it concurrently.

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

Successfully merging this pull request may close these issues.

2 participants