ожидание нескольких асин c звонков в java игре - PullRequest
0 голосов
/ 23 марта 2020

Я новичок в игре, и у меня возникла проблема, связанная с извлечением данных из нескольких URL-адресов, и я жду всех этих запросов.

Наверное, я что-то упускаю из-за асинхронных c действий, потому что когда я жду Примерно через полминуты для ответа в сеансе отладки я получаю желаемый результат, что означает, что он не ожидает запросов.

Я пытался сделать это с CompletableFuture.allOf, но я не знаю, почему это терпит неудачу. Кстати, я заметил, что этот метод возвращает CompletableFuture, поэтому мне интересно, как я могу затем ApplyAsyn c результат.

Я считаю, что проблема в retrieveCommitsForUser (одна из перегрузок) ... Я добавляю код здесь .

Заранее всем спасибо!

package controllers;

import com.fasterxml.jackson.databind.JsonNode;
import play.libs.Json;
import play.mvc.*;
import utils.BBService;

import javax.inject.Inject;
import java.util.List;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;

/**
 * Commits controller is handling in and out http traffic regarding bitbucket commits.
 * Supporting get but can be expanded to other crud operations.
 */
public class CommitsController extends Controller {

    final private String BB_BASE_URL = "https://api.bitbucket.org/2.0/";
    final private String URL = BB_BASE_URL + "********************/";
    final private String COMMITS = "commits";
    private BBService bbService;

    @Inject
    public CommitsController(BBService bbService) {
        this.bbService = bbService;
    }

    public CompletionStage<Result> showCommits(String username) {
        return bbService.getAsync(URL)
                .thenApplyAsync(wsResponse -> bbService.extractRepos(wsResponse))
                .thenApplyAsync(repos -> {
                    List<String> reposURL = repos.stream().map(repo -> URL + repo + "/" + COMMITS).collect(Collectors.toList());
                    return bbService.retrieveCommitsForUser(reposURL, username);
                })
                .thenApplyAsync(allCommits -> {
                    JsonNode commitsResult = Json.toJson(allCommits);
                    return bbService.withFullAccess(ok(commitsResult));
                });
    }
}

package utils;

import com.fasterxml.jackson.databind.JsonNode;
import models.Commit;
import play.libs.ws.*;
import play.mvc.Result;

import javax.inject.Inject;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;


public class BBService {

    private final String bbUsername = "*******";
    private final String bbPassword = "***********";
    private final WSClient ws;

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

    public CompletionStage<WSResponse> getAsync(String url) {
        WSRequest req = ws.url(url).setAuth(bbUsername, bbPassword);
        return req.get();
    }

    public List<String> extractNames(WSResponse wsResponse) {
        Vector<String> usersNames = new Vector<>();
        JsonNode users = wsResponse.asJson().findValue("values");

        for (JsonNode user : users) {
            String userName = user.findValue("display_name").asText();
            usersNames.add(userName);
        }

        return usersNames;
    }

    public CompletionStage<List<Commit>> retrieveCommitsForUser(String repoURL, String username) {
        return getAsync(repoURL)
                .thenApplyAsync(wsResponse -> extractCommits(wsResponse).stream()
                .filter(commit -> commit.getAuthor() == username)
                .collect(Collectors.toList()));
    }

    private List<Commit> extractCommits(WSResponse wsResponse) {
        Vector<Commit> allCommits = new Vector<>();
        JsonNode commits = wsResponse.asJson().findValue("values");

        for (JsonNode commit : commits) {
            String HASH = commit.findValue("hash").asText();
            String date = commit.findValue("date").asText();
            String repo = commit.findValue("repository").findValue("name").asText();
            String message = commit.findValue("message").asText();
            String author = commit.findValue("author").findValue("user").findValue("display_name").asText();

            Commit currCommit = new Commit(HASH, date, repo, message, author);
            allCommits.add(currCommit);
        }

        return allCommits;
    }

    public CompletableFuture<Void> retrieveCommitsForUser(List<String> reposURL, String username) {
        Vector<CompletableFuture<List<Commit>>> allCommits = new Vector<>();
//        reposURL.stream().forEach(repoURL -> allCommits.add(retrieveCommitsForUser(repoURL, username).toCompletableFuture()));
        for (String url: reposURL) {
            allCommits.add(retrieveCommitsForUser(url, username).toCompletableFuture());
        }
        return CompletableFuture.allOf(allCommits.toArray(new CompletableFuture[allCommits.size()]));
    }

    public List<String> extractRepos(WSResponse wsResponse) {
        Vector<String> repos = new Vector<>();
        JsonNode reposAsJson = wsResponse.asJson().findValue("values");

        for (JsonNode repo : reposAsJson) {
            String repoName = repo.findValue("slug").asText();
            repos.add(repoName);
        }

        return repos;
    }

    public Result withFullAccess(Result noAccessibleRes) {
        return noAccessibleRes.withHeader("Access-Control-Allow-Origin", "*");
    }
}

...