Skip to content

Commit 4256c8a

Browse files
authored
Add ability to cancel service call (#54)
* feat: Add cancel method to ServiceCall * test: Add test to verify new cancel functionality
1 parent 56b24f6 commit 4256c8a

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

src/main/java/com/ibm/cloud/sdk/core/http/ServiceCall.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,9 @@ public interface ServiceCall<T> {
5353
* @return a Single object containing the service call to be observed/subscribed to
5454
*/
5555
Single<Response<T>> reactiveRequest();
56+
57+
/**
58+
* Cancel the current request if possible.
59+
*/
60+
void cancel();
5661
}

src/main/java/com/ibm/cloud/sdk/core/service/BaseService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,11 @@ public com.ibm.cloud.sdk.core.http.Response<T> call() throws Exception {
424424
});
425425
}
426426

427+
@Override
428+
public void cancel() {
429+
this.call.cancel();
430+
}
431+
427432
@Override
428433
protected void finalize() throws Throwable {
429434
super.finalize();

src/test/java/com/ibm/cloud/sdk/core/test/service/ResponseTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
import static org.junit.Assert.assertEquals;
1616
import static org.junit.Assert.assertNotNull;
1717
import static org.junit.Assert.assertNull;
18+
import static org.junit.Assert.assertTrue;
1819

1920
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.List;
23+
import java.util.concurrent.TimeUnit;
2224

2325
import org.junit.Before;
2426
import org.junit.Test;
@@ -351,4 +353,49 @@ public void testResponseMessage() {
351353
assertEquals("The response status message should be 'No Content'.", "No Content", response.getStatusMessage());
352354
}
353355

356+
/**
357+
* Test canceling a service call by mimicking setting a timeout and canceling if the call exceeds that value.
358+
*
359+
* @throws InterruptedException the interrupted exception
360+
*/
361+
@Test
362+
public void testRequestCancel() throws InterruptedException {
363+
server.enqueue(new MockResponse().setBody(testResponseBody1).setBodyDelay(5000, TimeUnit.MILLISECONDS));
364+
365+
// time to consider timeout (in ms)
366+
long timeoutThreshold = 3000;
367+
final boolean[] hasCallCompleted = {false};
368+
final boolean[] callWasCanceled = {false};
369+
370+
ServiceCall<TestModel> testCall = service.getTestModel();
371+
long startTime = System.currentTimeMillis();
372+
testCall.enqueue(new ServiceCallback<TestModel>() {
373+
@Override
374+
public void onResponse(Response<TestModel> response) {
375+
hasCallCompleted[0] = true;
376+
System.out.println("We got a response!");
377+
}
378+
379+
@Override
380+
public void onFailure(Exception e) {
381+
callWasCanceled[0] = true;
382+
System.out.println("The request failed :(");
383+
}
384+
});
385+
386+
// keep waiting for the call to complete while we're within the timeout bounds
387+
while (!hasCallCompleted[0] && (System.currentTimeMillis() - startTime < timeoutThreshold)) {
388+
Thread.sleep(500);
389+
}
390+
391+
// if we timed out and it's STILL not complete, we'll just cancel the call
392+
if (!hasCallCompleted[0]) {
393+
testCall.cancel();
394+
}
395+
396+
// sleep for a bit to make sure all async operations are complete, and then verify we set this value
397+
// in onFailure()
398+
Thread.sleep(500);
399+
assertTrue(callWasCanceled[0]);
400+
}
354401
}

0 commit comments

Comments
 (0)