Skip to content

Commit

Permalink
#194: Some java client wait APIs could incorrectly exit due to overflow.
Browse files Browse the repository at this point in the history
Summary: When the passed in timeout was maximum long value, the summation was hitting errors. Made it a subtraction at couple of places.

Test Plan:
Added unit test.

Jenkins

Reviewers: bogdan

Reviewed By: bogdan

Subscribers: ybase

Differential Revision: https://phabricator.dev.yugabyte.com/D4643
  • Loading branch information
bbaddepudi committed Apr 19, 2018
1 parent b125942 commit d6d130b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
23 changes: 21 additions & 2 deletions java/yb-client/src/main/java/org/yb/client/YBClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ public class YBClient implements AutoCloseable {
// Log info after these many iterations.
private static final int LOG_EVERY_NUM_ITERS = 200;

// Simple way to inject an error on Wait based APIs. If enabled, after first inject,
// it will be turned off. We can enhance it to use more options like every-N etc.
private boolean injectWaitError = false;

public YBClient(AsyncYBClient asyncClient) {
this.asyncClient = asyncClient;
}
Expand Down Expand Up @@ -450,7 +454,7 @@ private String waitAndGetLeaderMasterUUID(long timeoutMs) throws Exception {
}

Thread.sleep(asyncClient.SLEEP_TIME);
} while (System.currentTimeMillis() < start + timeoutMs);
} while (System.currentTimeMillis() - start < timeoutMs);

LOG.error("Timed out getting leader uuid.");

Expand Down Expand Up @@ -696,6 +700,14 @@ public boolean get() throws Exception {
}
}

/**
* Quick and dirty error injection on Wait based API's.
* After every use, for now, will get automatically disabled.
*/
public void injectWaitError() {
injectWaitError = true;
}

/**
* Helper method that loops on a condition every 500ms until it returns true or the
* operation times out.
Expand All @@ -711,6 +723,13 @@ private boolean waitForCondition(Condition condition, final long timeoutMs) {
String errorMessage = null;
do {
try {
if (injectWaitError) {
Thread.sleep(AsyncYBClient.SLEEP_TIME);
injectWaitError = false;
String msg = "Simulated expection due to injected error.";
LOG.info(msg);
throw new RuntimeException(msg);
}
if (condition.get()) {
return true;
}
Expand All @@ -737,7 +756,7 @@ private boolean waitForCondition(Condition condition, final long timeoutMs) {
try {
Thread.sleep(AsyncYBClient.SLEEP_TIME);
} catch (Exception e) {}
} while (System.currentTimeMillis() < start + timeoutMs);
} while (System.currentTimeMillis() - start < timeoutMs);

if (errorMessage == null) {
LOG.error("Timed out waiting for operation. Final exception was {}.",
Expand Down
11 changes: 11 additions & 0 deletions java/yb-client/src/test/java/org/yb/client/TestYBClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ public void testClientCreateDestroy() throws Exception {
}
}

/**
* Test Waiting for load balance, with simulated errors.
* @throws Exception
*/
@Test(timeout = 100000)
public void testWaitForLoadBalance() throws Exception {
syncClient.injectWaitError();
boolean isBalanced = syncClient.waitForLoadBalance(Long.MAX_VALUE, 0);
assertTrue(isBalanced);
}

/**
* Test Master Configuration Change operation going from A,B,C to D,E,F.
* @throws Exception
Expand Down

0 comments on commit d6d130b

Please sign in to comment.