Я работаю в приложении Scala, используя Slick и PostgreSQL для хранения. У меня есть метод foo
, который читает данные из файла CSV и вставляет около 10000 строк в базу данных. После завершения действия Future of the insert строки вызывается другой метод bar
, который извлекает эти строки из базы данных и выполняет с ними некоторые действия. Вот в чем проблема: на самом деле из базы данных не извлекаются строки, так как к моменту завершения Future строк не было вставлено.
Из того, что я мог собрать, ища ответ и в официальной документации, Future не должен завершаться до успешного выполнения оператора вставки. Если я добавлю следующий код Thread.sleep(30000)
к bar
, позволяя сначала выполнить оператор вставки, методы обеспечат ожидаемый результат. Теперь по понятным причинам я бы предпочел не делать этого, поэтому я ищу альтернативы.
Следующая диаграмма иллюстрирует ход выполнения программы после вызова начального метода doStuff
:
doStuff
вызывает foo
, который загружает данные и сохраняет их в базе данных перед возвратом в будущее. В doStuff
это Будущее затем отображается и делается вызов bar
. bar
бар извлекает строки из базы данных и обрабатывает их. Однако, поскольку в точке, где вызывается bar
, не было вставлено ни одной строки, данные не обрабатываются.
Метод doStuff
:
def doStuff(csvFile: File): Future[Unit] = {
fooService.foo(csvFile)
.map(_ => {
csvFile.delete()
barService.bar()
})
}
Метод foo
:
def foo(file: File) Future[Unit] = {
val reader = CSVReader.open(file)
fooStorage.truncateFooData().map(_ => {
val foos = for (line <- reader.iterator if
line.head != "bad1" &&
line.head !="bad2")
yield parseFooData(line)
fooStorage.saveFooDataBulk(foos.toSeq)
})
}
Как я использую Slick для вставки строк:
override def saveFooDataBulk(fooSeq: Seq[Foo]): Future[Seq[Foo]] =
db.run(DBIO.seq(fooQuery ++= fooSeq)).map(_ => fooSeq)
Я ожидаю, что bar
будет вызван, как только все строки будут вставлены в базу данных, и не раньше, однако, в настоящее время Future from Slick завершает работу слишком рано. В случае, если это уместно: метод doStuff
вызывается при отправке запроса в конечную точку HKK Akka. Приложение и база данных работают в двух разных контейнерах Docker. Что я делаю не так?
Также я не могу понять, насколько подходящим является имя пользователя, которое я выбрал полтора года назад.