Я пытаюсь понять, как выполнить пакетное сохранение выбранных объектов и сохранить их в базе данных.После сохранения объектов в базе данных я хочу вернуть результат запроса.Я не могу понять, как это сделать с EventLoopFuture, так как, когда я вызываю .wait()
, я получаю сообщение об ошибке:
Предварительное условие не выполнено: ОБНАРУЖЕНА БАГ: ожидание () не должно вызываться, когда на EventLoop.
В качестве примера моей проблемы:
- Мне нужно получить объект из внешней конечной точки (скажем, рейсы в аэропорт)
- Результат этого вызова должен быть сохранен в базе данных.Если рейс существует в базе данных, его необходимо обновить, если он создан.
- По завершении необходимо вернуть список всех рейсов из базы данных.
Этоэто то, что я получил до сих пор, но это дает мне ошибку:
func flights(on conn: DatabaseConnectable, customerName: String, flightType: FlightType) throws -> Future<[Flight]> {
return Airport.query(on: conn).filter(\.customerName == customerName).first().flatMap(to: [Flight].self) { airport in
guard let airport = airport else {
throw Abort(.notFound)
}
guard let airportId = airport.id else {
throw Abort(.internalServerError)
}
// Update items for customer
let fetcher: AirportManaging?
switch customerName.lowercased() {
case "coolCustomer":
fetcher = StoreOneFetcher()
default:
fetcher = nil
debugPrint("Unhandled customer to fetch from!")
// Do nothing
}
let completion = Flight.query(on: conn).filter(\.airportId == airportId).filter(\.flightType == flightType).all
guard let flightFetcher = fetcher else { // No customer fetcher to get from, but still return whats in the DB
return completion()
}
return try flightFetcher.fetchDataForAirport(customerName, on: conn).then({ (flights) -> EventLoopFuture<[Flight]> in
flights.forEach { flight in
_ = try? self.storeOrUpdateFlightRecord(flight, airport: airport, on: conn).wait()
}
return completion()
})
}
}
func storeOrUpdateFlightRecord(_ flight: FetcherFlight, airport: Airport, on conn: DatabaseConnectable) throws -> EventLoopFuture<Flight> {
guard let airportId = airport.id else {
throw Abort(.internalServerError)
}
return Flight.query(on: conn).filter(\.itemName == flight.itemName).filter(\.airportId == airportId).filter(\.flightType == flight.type).all().flatMap(to: Flight.self) { flights in
if let firstFlight = flights.first {
debugPrint("Found flight in database, updating...")
return flight.toFlight(forAirport: airport).save(on: conn)
}
debugPrint("Did not find flight, saving new...")
return flight.toFlight(forAirport: airport).save(on: conn)
}
}
Так что проблема в строке _ = try? self.storeOrUpdateFlightRecord(flight, airport: airport, on: conn).wait()
.Я не могу позвонить wait()
, так как он заблокирует EventLoop, но если я позвоню map
или flatMap
, мне нужно, в свою очередь, вернуть EventLoopFuture<U>
(U
, являющийся Flight
), который я совершенно не заинтересован
Я хочу, чтобы вызывался self.storeOrUpdateFlightRecord
, а результат игнорировался.Как я могу это сделать?