504 occur due to calling WS request

My project devided into multiple modules. each module have it’s play project (own docker).
For example Play Docker A, Play Docker B , where i calling REST API of Docker A and internally Docker A calling REST API of Docker B for getting some another data. now when i calling that API (Docker B ) using Play WS then it’s called but it returns 504 for Docker A API called response.i am using supply async method for whole project.

Please help me i try lots of thing but not getting success.

Hi @Paresh78,

make sure the code works when run outside docker containers. Start the two play services in a single machine (without any docker containarization) and run your test. If that works, the likely cause is an error setting up networking between the two containers which leads to a 504 Gateway Timeout from the client: the client fails to reach the server. If that’s the case, review all ports your play application opens are exposed outside the docker container and routing is setup correctly.

Regards,

Hi @ignasi35

I am working with @Paresh78 and here are the actual scenario.

I have posted on SO.

Please have a look.

I had a look and can only say what other’s already commented: there’s not enough information. In any case, it’s better to continue the conversation in a single location (either SO or here).

This is the proper place to discuss this. And you were right there was not enough info regarding the issue. so let me put my code and explain you better.

MyClient Class for WS Get request

public class MyClient implements WSBodyReadables, WSBodyWritables {
private final WSClient ws;

@Inject
public MyClient(WSClient ws) {
    this.ws = ws;
}

public void doGetCall() {
    WSRequest request = ws.url("http://dummy.restapiexample.com/api/v1/employees");
    WSRequest complexRequest = request
                    .setRequestTimeout(Duration.of(1000, ChronoUnit.MILLIS));
    CompletionStage<WSResponse> responsePromise = complexRequest.get();
    try {
        String response = responsePromise.toCompletableFuture().get().getBody();
        System.out.println("API : " + response);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

}

JPAPostRepository from the play-rest-example (JPA backend)

@Singleton
public class JPAPostRepository implements PostRepository {

private final JPAApi jpaApi;
private final PostExecutionContext ec;
private final CircuitBreaker<Optional<PostData>> circuitBreaker = new CircuitBreaker<Optional<PostData>>().withFailureThreshold(1).withSuccessThreshold(3);

@Inject
MyClient myClient;

@Inject
public JPAPostRepository(JPAApi api, PostExecutionContext ec) {
    this.jpaApi = api;
    this.ec = ec;
}

@Override
public CompletionStage<Stream<PostData>> list() {
    return supplyAsync(() -> wrap(em -> select(em)), ec);
}

private <T> T wrap(Function<EntityManager, T> function) {
    return jpaApi.withTransaction(function);
}

private Optional<PostData> lookup(EntityManager em, Long id) throws SQLException {
    throw new SQLException("Call this to cause the circuit breaker to trip");
}

private Stream<PostData> select(EntityManager em) {
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();

    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();

    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    myClient.doGetCall();
    System.out.println("done");
    TypedQuery<PostData> query = em.createQuery("SELECT p FROM PostData p", PostData.class);
    return query.getResultList().stream();
}

}

So after running the server and when I call this below link
http://localhost:9000/v1/posts
which eventually call this function from the above class

@Override
public CompletionStage<Stream> list() {
return supplyAsync(() → wrap(em → select(em)), ec);
}

So this http://localhost:9000/v1/posts
API gives 504 but the WS calls are executed successfully.

I know I have put the get api call more then needed but this to show case the 504 timeout. And what if we want to call these kind of apis. can we increase default gateway timeout from play framework.

Hope this will help you to understand our issue.

@ignasi35 can you please check the above case? I am not getting why framework throws 504 error in less then 2 seconds?