scala-async
scala-async copied to clipboard
Awaitable operations inside try block
Why not support awaitable operations inside try block, by translating try{ F } catch { G } finally { H } to something like: async(F).recoverWith(G).onComplete(H) ?
Probably because this is incompatible with the machine state.
I did a await/async for jvm some time ago: https://github.com/soywiz/jawaitasync
But at bytecode level. Manipulating the AST is a different story.
But that doesn't mean that supporting try...catch blocks, is impossible.
I have another proposal implementing this: (Simplified, and don't know about the implementation, so this is pseudocode)
try {
stm1
val result = await(future1)
stm2
} catch (e) {
case e:Exception =>
}
->
class MachineState(var local1, var local2, var state, var error)
while (state.state != 5) {
state.state match {
case 0 => try { stm1; state.state = 1 } catch (e) { state.state = 4 }
case 1 => try {
future1.then(v => resume(2, v, null))).otherwise(e => resume(4, null, e))
return
}
case 2 => try { stm1; state.state = 3 } catch (e) { state.state = 4 }
case 3 => done()
case 4 => {
// Transform the match from the catch statement, with a normal match
e match {
case e:Exception => state.state = ...
}
}
}
}
I implemented support for await within try-catch-finally a while ago, however, without a substantial rebase we couldn't integrate it: https://github.com/phaller/async/tree/topic/try-catch-finally
Contributions for porting this to the current 2.10.x branch are most welcome!
The rebase is just merge manually all the commits related to try-catch-finally? Or the api has changed since then?
A few things internal to the async implementation were changed, but it's possible that the try-catch-finally support "just works" (at least as far as it's implemented). So, yes, I think the main part of the work is manually merging all the commits related to try-catch-finally.
Following a PR, there might be a few more issues to address, of course. Just to be clear that the implementation is probably not 100% done. :-)
I believe we can and should do better than generating a PartialFunction for each catch handler. Instead, these could be additional states in the state machine.