Home > Mobile >  How do you thread a fire and forget future into a for comprehension?
How do you thread a fire and forget future into a for comprehension?

Time:12-18

I have a use case that involves dealing with a file upload in 3 steps:

  1. Create entry in DB
  2. Extract metadata from the file and store in DB using previous id
  3. Store file in cloud folder

I want Step 2 to happen in a fire and forget manner but it requires the id from step 1. I want steps 1 and 3 to happen synchronously and return as fast as possible. My code looks like:

def storeFile(): Future[Long]
def extractAndSaveMetadata(id:Long, content:Bytestring) : Future[Unit]
def storeFile(id, Long, content:ByteString): Future[Unit]

for {
  id <- createEntryInDB()
  _ <- extractAndSaveMetadata(id, content)
  _ <- storeFile(id, content)
} yield ()

The problem with this approach is that step 2 is very slow and there is no problem with making it eventually consistent. At the same time it requires the value from step 1 so I don't know how to un-thread the fire and forget call in this monadic sequence of calls.

Is there a way to "fork" a future execution within a Future for-comprehension?

CodePudding user response:

Yeah, the solution was pointed by @SwiftMango. The code translates into:

for {
  id <- createEntryInDB()
  _ = extractAndSaveMetadata(id, content)
  _ <- storeFile(id, content)
} yield ()

Other suggested approaches in the comments don't work because:

  • I don't want to return after either extractAndSaveMetadata or storeField returns. There is only 1 main path that is createEntry andThen storeFile
  • It is indeed a sequence of tasks, without the id in the first task you cannot run 2 and 3.
  • Using Future.sequence would block the whole thread upstream until all futures are completed. I want to return control ASAP.
  • Related