import ballerina/http;
import ballerina/log;
import ballerina/runtime;
http:Client backendClientEP = new ("http://localhost:8080", {
retryConfig: {
intervalInMillis: 3000,
count: 3,
backOffFactor: 2.0,
maxWaitIntervalInMillis: 20000
},
timeoutInMillis: 2000
}
);@http:ServiceConfig {
basePath: "/retry"
}
service retryDemoService on new http:Listener(9090) {
@http:ResourceConfig {
methods: ["GET"],
path: "/"
}
resource function invokeEndpoint(http:Caller caller, http:Request request) {
var backendResponse = backendClientEP->forward("/hello", request);
if (backendResponse is http:Response) {
var responseToCaller = caller->respond(backendResponse);
if (responseToCaller is error) {
log:printError("Error sending response", responseToCaller);
}
} else {
http:Response response = new;
response.statusCode = http:STATUS_INTERNAL_SERVER_ERROR;
string errCause = <string>backendResponse.detail()?.message;
response.setPayload(errCause);
var responseToCaller = caller->respond(response);
if (responseToCaller is error) {
log:printError("Error sending response", responseToCaller);
}
}
}
}int counter = 0;
@http:ServiceConfig {
basePath: "/hello"
}
service mockHelloService on new http:Listener(8080) { @http:ResourceConfig {
methods: ["GET", "POST"],
path: "/"
}
resource function sayHello(http:Caller caller, http:Request req) {
counter = counter + 1;
if (counter % 4 != 0) {
log:printInfo(
"Request received from the client to delayed service.");
runtime:sleep(5000);
var responseToCaller = caller->respond("Hello World!!!");
handleRespondResult(responseToCaller);
} else {
log:printInfo(
"Request received from the client to healthy service.");
var responseToCaller = caller->respond("Hello World!!!");
handleRespondResult(responseToCaller);
}
}
}function handleRespondResult(error? result) {
if (result is http:ListenerError) {
log:printError("Error sending response from mock service", result);
}
}# To start the services, navigate to the directory that contains the
# `.bal` file and use the `ballerina run` command below.
ballerina run http_retry.bal.bal
[ballerina/http] started HTTP/WS listener 0.0.0.0:9090
[ballerina/http] started HTTP/WS listener 0.0.0.0:8080
2019-09-04 15:47:25,980 INFO [] - Request received from the client to delayed service.
2019-09-04 15:47:30,998 INFO [] - Request received from the client to delayed service.
2019-09-04 15:47:31,012 ERROR [] - Error sending response from mock service : error {ballerina/http}GenericListenerError message=Connection between remote client and host is closed
2019-09-04 15:47:36,004 ERROR [] - Error sending response from mock service : error {ballerina/http}GenericListenerError message=Connection between remote client and host is closed
2019-09-04 15:47:39,005 INFO [] - Request received from the client to delayed service.
2019-09-04 15:47:44,007 ERROR [] - Error sending response from mock service : error {ballerina/http}GenericListenerError message=Connection between remote client and host is closed
2019-09-04 15:47:53,016 INFO [] - Request received from the client to healthy service.# If the request that was sent to the `retryDemoService` fails due to an error, the client tries sending the request again.
curl -v http://localhost:9090/retry
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 9090 (#0)
> GET /retry HTTP/1.1
> Host: localhost:9090
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: text/plain
< date: Wed, 4 Sep 2019 15:47:53 +0530
< server: ballerina/1.0.0-beta
< content-length: 14
<
* Connection #0 to host localhost left intact
Hello World!!!
RetryThe HTTP retry client tries sending over the same request to the backend service when there is a network level failure. |
|
|
|
Define the endpoint to the call the |
|
Retry configuration options. |
|
Initial retry interval in milliseconds. |
|
Number of retry attempts before giving up. |
|
Multiplier of the retry interval to exponentially increase the retry interval. |
|
Upper limit of the retry interval in milliseconds. If
|
|
|
|
Create a REST resource within the API. |
|
Parameters include a reference to the caller and an object of the request data. |
|
If |
|
|
|
This sample service is used to mock connection timeouts and service outages.
The service outage is mocked by stopping/starting this service.
This should run separately from the |
|
|
|
Delay the response by 5000 milliseconds to mimic network level delays. |
|
|
|