Получение списка с помощью фреймворка Lagom

Я ОЧЕНЬ новичок в фреймворке Lagom и совершенно не понимаю, что делаю. У меня есть простое приложение CRUD lagom, которое работает, но я не могу понять, как получить список.

Так что это то, что у меня есть на данный момент, но я получаю

@Override
    public ServiceCall<NotUsed, Source<Movie, ?>> getMovies() {
        return request -> {
            CompletionStage<Source<Movie, ?>> movieFuture = session.selectAll("SELECT * FROM movies")
                    .thenApply(rows -> rows.stream()
                    .map(row -> Movie.builder()
                        .id(row.getString("id"))
                        .name(row.getString("name"))
                        .genre(row.getString("genre"))
                        .build()));
                    //.thenApply(TreePVector::from));
                    //.thenApply(is -> is.collect(Collectors.toList()))

            return movieFuture;
        };
    }

но я получаю ошибку [Java] Type mismatch: cannot convert from Stream<Object> to Source<Movie,?> в строке rows.stream().

Любая помощь будет оценена по достоинству.

Заранее спасибо.


person OguzGelal    schedule 27.04.2017    source источник


Ответы (1)


Похоже, тип возвращаемого значения должен быть Source (из Akka Reactive Streams), но вы создаете Java 8 Stream.

Проблема может быть легко решена, если вы использовали select вместо selectAll при запросе к базе данных. CassandraSession от Lagom предоставляет два семейства методов для запросов к БД: (1) select(...) немедленно вернет Source<Row,NotUsed>, который является реактивным потоком, или (2) selectAll(...), который соберет все строки в памяти и вернет List<Row>. Последний может вывести из строя ваш сервер, потому что попытается поместить всю информацию в память. Первый будет использовать реактивные потоки для доставки элементов, адаптируя скорость к конечной скорости потребления (противодавлению), сохраняя при этом очень низкий объем памяти.

Ваш код можно переписать как:

 public ServiceCall<NotUsed, Source<GreetingMessage, ?>> getGreetings() {
    return request ->
         CompletableFuture.completedFuture(
              session.select("SELECT * FROM greetings")
                     .map(row -> new GreetingMessage(row.getString(0)))
          );
 }

Использование select создает файл Source<>. Вы можете сопоставлять элементы по отдельности на этом Source<>, используя уже разработанную вами лямбду.

person ignasi35    schedule 27.04.2017
comment
Спасибо! Теперь мой код, похоже, компилируется, но теперь, когда я делаю запрос, я получаю HTTP-ответ 426 Update Required с сообщением «Требуется обновление до WebSocket». Есть идеи ? - person OguzGelal; 27.04.2017
comment
Каждый раз, когда ваш ServiceCall использует Source в одном из своих параметризованных типов (как вы делаете с типом ответа), Lagom реализует вызов с использованием веб-сокетов. Вам нужен клиент, который может обновить протокол до веб-сокетов (и это то, что говорит 426... ;-)) - person ignasi35; 03.05.2017