Reputation: 11751
I currently have a method that updates a Redis table based on a Future[String]
.
def update(key: String, timeStamp: Long, jsonStringF: Future[String], redisClient: RedisClient) = {
jsonStringF.map { jsonString =>
val historyKey = "history." + key
val tempKey = "temp." + key
val tran = redisClient.transaction()
tran.zadd(historyKey, (timeStamp, jsonString))
tran.del(tempKey)
val f = tran.exec()
f.onComplete {
case Success(suc) => dlogger.info(s"Updated $historyKey and deleted $tempKey successfully ....")
case Failure(ex) => dlogger.warn(s"Error updating tables", ex)
}
}
}
Now I've two Future[String]
(jsonStringF1
and jsonStringF2
) and I want to update two different tables.
def update(key: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2: Future[String], redisClient: RedisClient) = {
....
}
I want to update another table ("another." + key
) with String
in jsonStringF2
. How can I do that ?
UPDATE: Is the code below correct?
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2: Future[String], redisClient: RedisClient) =
{
for {
a <- jsonStringF1
t <- jsonStringF2
historyKey = "history." + tableKey
anotherKey = "another." + tableKey +
tempKey = "temp." + tableKey
tran = redisClient.transaction()
_ = tran.zadd(historyKey, (timeStamp, a))
_ = tran.zadd(anotherKey, (timeStamp, t))
_ = tran.del(tempKey)
f = tran.exec()
} yield ()
}
Upvotes: 2
Views: 184
Reputation: 190
Since you have just 2 Futures you can zip them:
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2:Future[String], redisClient: RedisClient) = {
val jsons = jsonStringF1.zip(jsonStringF2)
jsons map {
case (a, t) =>
val historyKey = "history." + tableKey
val anotherKey = "another." + tableKey
val tran = redisClient.transaction()
tran.zadd(historyKey, (timeStamp, a))
tran.zadd(anotherKey, (timeStamp, t))
tran.del(tempKey)
tran.exec()
}
}
Upvotes: 0
Reputation: 7735
You can use for loop, as you described
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2:Future[String], redisClient: RedisClient) = {
for {
a <- jsonStringF1
t <- jsonStringF2
} yield {
val historyKey = "history." + tableKey
val anotherKey = "another." + tableKey
val tran = redisClient.transaction()
tran.zadd(historyKey, (timeStamp, a))
tran.zadd(anotherKey, (timeStamp, t))
tran.del(tempKey)
tran.exec()
}
}
As an alternative to for you can also use scala/async (https://github.com/scala/async) and write your code like this
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2:Future[String], redisClient: RedisClient) = {
async {
val a = await(jsonStringF1)
val t = await(jsonStringF2)
val historyKey = "history." + tableKey
val anotherKey = "another." + tableKey
val tran = redisClient.transaction()
tran.zadd(historyKey, (timeStamp, a))
tran.zadd(anotherKey, (timeStamp, t))
tran.del(tempKey)
tran.exec()
}
}
Which will also be nonblocking. Async has slight advantage, since
async blocks are compiled to a single anonymous class, as opposed to a separate anonymous class for each closure required at each generator.
Upvotes: 3
Reputation: 658
Your can collect multiple futures using a for
:
val f1: Future[String] = ...
val f2: Future[String] = ...
for {
a <- f1
b <- f2
} {
// Code to execute when both f1 and f2 complete
// a and b are available here
}
Upvotes: 3