在构建具有收益结构的期货时,有些有副作用,有些没有,我引入了竞争条件,因为依赖于副作用的未来没有将副作用的结果作为论据。
简而言之:
未来b读取的值因来自未来a的副作用而改变 ,但未来a不明确依赖于未来b的结果,因此可能在b完成读取之前发生。
为了解决这个问题,我的同事引入了一个虚拟函数,将b的结果作为参数并简单地将其丢弃。这样做是为了使依赖关系明确。
实际代码在这里:
val futureConnection:Future[(Either[String, (Connection)],Boolean)] =
for {
scannerUser <- scanner.orFail("Scanning user not found")
scannedUser <- futureScannedUser.orFail("Scanned user not found")
existsInAnyDirection <- connections.existsInAnyDirection(scannerUser, scannedUser)
connection <- connections.createConnection(scannerUser, scannedUser, form.magicWord, existsInAnyDirection)
} yield {
(connection, existsInAnyDirection)
}
在这种情况下,未来b是
connections.existsInAnyDirection(scannerUser, scannedUser)
带有虚拟参数的未来a 是
connections.createConnection(scannerUser, scannedUser, form.magicWord, existsInAnyDirection)
请注意,该参数existsInAnyDirection
从未在内部使用createConnection
。这有效地创建了在 existsInAnyDirection 完成之前无法启动 createConnection 的依赖关系图。
现在的问题:
有没有更明智的方法来明确依赖关系?
奖金信息
我自己的挖掘告诉我,Scala Futures 根本不能很好地处理副作用。Future trait上处理副作用的方法返回 Unit,而从副作用操作中读取的结果很可能,即错误代码、生成的 ID、任何其他元信息,真的。