Created
September 17, 2020 03:37
-
-
Save nsivabalan/9743c8b59c814d9c6ad6b2f65aab7ac0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.ubercab.network.ramengrpc; | |
| import java.util.concurrent.atomic.AtomicBoolean; | |
| public class CustomStopWatch implements Runnable { | |
| private final long timeoutMs; | |
| private final TimeoutCallBack callBack; | |
| private AtomicBoolean eventTriggered = new AtomicBoolean(false); | |
| private AtomicBoolean shutdownInvoked = new AtomicBoolean(false); | |
| private AtomicBoolean paused = new AtomicBoolean(false); | |
| public CustomStopWatch(TimeoutCallBack callBack, long timeoutMs) { | |
| this.callBack = callBack; | |
| this.timeoutMs = timeoutMs; | |
| } | |
| @Override | |
| public void run() { | |
| try { | |
| waitUntilTimeout(); | |
| } catch (InterruptedException e) { | |
| throw new IllegalStateException("IE thrown ", e); | |
| } | |
| } | |
| private synchronized void waitUntilTimeout() throws InterruptedException { | |
| while (!shutdownInvoked.get()) { // execute until shutdown is invoked | |
| eventTriggered.set(false); // reset eventTrigger just before going to wait | |
| this.wait(timeoutMs); | |
| if (!shutdownInvoked.get() && !paused.get()) { // if shutdown is not called and not paused | |
| // if shutdown not invoked | |
| if (!eventTriggered.get()) { // if no event has been triggered within timeout, then invoke | |
| // timeout callback | |
| callBack.onTimeout(); | |
| // what to do after calling timeout. | |
| /* | |
| // may be put to pause state. Caller is expected to call restart to resume. | |
| paused.set(true); | |
| while(!shutdownInvoked.get() && paused.get()) { | |
| // need a while loop, bcoz, if resetTimer is called while in paused state, should still | |
| // be in waiting | |
| this.wait(); | |
| } | |
| */ | |
| // if above code is uncommented, remove the break; | |
| break; | |
| } else { // if event has been triggered, go to next cycle of waiting | |
| // go back to wait again | |
| } | |
| } else if (!shutdownInvoked.get()) { // if paused | |
| while(!shutdownInvoked.get() && paused.get()) { | |
| // need a while loop, bcoz, if resetTimer is called while in paused state, should still | |
| // be in waiting | |
| this.wait(); | |
| } | |
| } | |
| } | |
| } | |
| public synchronized void shutdown() { | |
| shutdownInvoked.set(true); | |
| this.notifyAll(); | |
| } | |
| public synchronized void resetTimer() { | |
| eventTriggered.set(true); | |
| this.notifyAll(); | |
| } | |
| public synchronized void paused() { | |
| paused.set(true); | |
| notifyAll(); | |
| } | |
| public synchronized void restart() { | |
| paused.set(false); | |
| notifyAll(); | |
| } | |
| interface TimeoutCallBack { | |
| void onTimeout(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.ubercab.network.ramengrpc; | |
| import com.ubercab.test.UberTestBase; | |
| import java.util.concurrent.CountDownLatch; | |
| import java.util.concurrent.TimeUnit; | |
| import org.junit.Test; | |
| public class TestCustomStopWatch extends UberTestBase { | |
| @Test | |
| public void simpleTest1() throws InterruptedException { | |
| CountDownLatch countDownLatch = new CountDownLatch(1); | |
| TestTimeoutCallBack timeoutCallBack = new TestTimeoutCallBack(System.currentTimeMillis(), countDownLatch); | |
| CustomStopWatch stopWatch = new CustomStopWatch(timeoutCallBack, 2000); | |
| new Thread(stopWatch).start(); | |
| Thread.sleep(1000); | |
| // timeoutCallBack.startTimeMs = System.currentTimeMillis(); | |
| stopWatch.resetTimer(); | |
| countDownLatch.await(10, TimeUnit.SECONDS); | |
| System.out.println("First timeout completed "); | |
| // after timeout called, need to again restart the stopwatch | |
| timeoutCallBack.countDownLatch = new CountDownLatch(1); | |
| timeoutCallBack.startTimeMs = System.currentTimeMillis(); | |
| stopWatch.restart(); | |
| countDownLatch.await(10, TimeUnit.SECONDS); | |
| } | |
| @Test | |
| public void simpleTest2() throws InterruptedException { | |
| CountDownLatch countDownLatch = new CountDownLatch(1); | |
| TestTimeoutCallBack timeoutCallBack = new TestTimeoutCallBack(System.currentTimeMillis(), countDownLatch); | |
| CustomStopWatch stopWatch = new CustomStopWatch(timeoutCallBack, 2000); | |
| new Thread(stopWatch).start(); | |
| Thread.sleep(1000); | |
| timeoutCallBack.startTimeMs = System.currentTimeMillis(); | |
| stopWatch.resetTimer(); | |
| countDownLatch.await(10, TimeUnit.SECONDS); | |
| } | |
| @Test | |
| public void pauseTest() throws InterruptedException { | |
| CountDownLatch countDownLatch = new CountDownLatch(1); | |
| TestTimeoutCallBack timeoutCallBack = new TestTimeoutCallBack(System.currentTimeMillis(), countDownLatch); | |
| CustomStopWatch stopWatch = new CustomStopWatch(timeoutCallBack, 2000); | |
| new Thread(stopWatch).start(); | |
| Thread.sleep(1000); | |
| stopWatch.paused(); | |
| timeoutCallBack.startTimeMs = System.currentTimeMillis(); | |
| Thread.sleep(3000); | |
| System.out.println("stop watch paused"); | |
| stopWatch.restart(); | |
| countDownLatch.await(10, TimeUnit.SECONDS); | |
| } | |
| class TestTimeoutCallBack implements CustomStopWatch.TimeoutCallBack { | |
| long startTimeMs; | |
| CountDownLatch countDownLatch; | |
| public TestTimeoutCallBack(long startTimeMs, CountDownLatch countDownLatch) { | |
| this.startTimeMs = startTimeMs; | |
| this.countDownLatch = countDownLatch; | |
| } | |
| @Override | |
| public void onTimeout() { | |
| long curTime = System.currentTimeMillis(); | |
| System.out.println("Timeout called at "+ (curTime - startTimeMs) +", abs time " | |
| + System.currentTimeMillis()); | |
| this.countDownLatch.countDown(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment