Wrap Slick запросы в фьючерсах

Я пытаюсь запросить базу данных MySQL асинхронно, используя Slick. Следующий шаблон кода, который я использую для запроса примерно 90 тыс. Строк в понимании, кажется, работает изначально, но программа потребляет несколько гигабайт оперативной памяти и выходит из строя без предупреждения после примерно 200 запросов.

import scala.slick.jdbc.{StaticQuery => Q}
def doQuery(): Future[List[String]] = future {
  val q = "select name from person"
  db withSession {
    Q.query[String](q).list
  }
}

Я попытался настроить соединения как с помощью метода fromURL, так и с помощью пула соединений c3p0. Мой вопрос: это способ сделать асинхронные вызовы в базу данных?

Ответ 1

Async по-прежнему является открытой проблемой для Slick.

Вы можете попробовать использовать Iterables и данные потока вместо хранения в памяти с помощью решения, аналогичного этому: Обработка SQL ResultSet, как поток Scala

p >

Хотя, пожалуйста, опустите вызов .toStream в конце. Он будет кэшировать данные в памяти, в то время как Iterable не будет.

Если вы хотите асинхронную версию итерации, вы можете посмотреть Observables.

Ответ 2

Оказывается, что это не проблема (на самом деле ошибка в моем коде, которая открыла новое соединение с базой данных для каждого запроса). По моему опыту, вы можете обернуть запросы БД в Futures, как показано выше, и скомпилировать их позже Scala Async или Rx, как показано здесь. Все, что требуется для хорошей производительности, - это большой пул потоков (x2 CPU в моем случае) и одинаково большой пул соединений.

Ответ 3

Slick 3 (Reactive Slick) выглядит так, как будто он может решить эту проблему.