Hello, hello! How do we switch CoroutineContexts w...
# arrow
d
Hello, hello! How do we switch CoroutineContexts within
IO.fx { ... }
? I tried starting the block with
continueOn(<http://Dispatchers.IO|Dispatchers.IO>)
but for some reason it hangs.
d
Thanks for replying, Bob! Does this mean that
continueOn
is meant to be used with
async
and not
fx
?
b
ugh. Sorry, I totally misread your question. Just based on reading the
continueOn
example it may be that you will need to use that combinator outside of the
fx
block
because chain in the example is Async.just(...).continueOn(...).flatMap(...).continueOn(...).flatMap(...)
I'm not sure if that translates to `IO.fx { ... }`'s syntax
d
Ahh ok, I think I'm misusing the APIs with this example:
Copy code
IO.fx {
            continueOn(<http://Dispatchers.IO|Dispatchers.IO>)
            val inventory = !requestOperations.getInventory()
            continueOn(Dispatchers.Main)
            inventoryLiveData.value = inventory
        }
            .attempt()
            .unsafeRunSync()
            .fold(
                ifLeft = {
                    // handle error
                },
                ifRight = {
                    // completed
                }
            )
b
So I'm wondering if you can have something like this:
Copy code
IO.unit.continueOn(Dispatchers.Main).flatMap { IO.fx { ... } }
but I'll admit I don't know if that works or even yields the correct behavior
d
well, that definitely worked!
b
I'm happy to hear that! I think
continueOn
has to happen at IO "program" boundaries
basically
IO.continueOn(...).flatMap(IO).continueOn(...).flatMap(IO)...
but @simon.vergauwen or @pakoito or @raulraja will have to chime in on whether that assumption is correct or not
p
when you do
unsafeRunSync
you’re blocking the current thread, which I’ll assume is the main thread. Then inside the IO you try to return back but it’s blocked
use
unsafeRunAsync { /* NOTHING */ }
and it you want to display something on the UI do it on the fx block
it’s a bad habit we got with Rx
myOperation.observeOn(Main).subscribe { ui() }
where it should be
myOperation.observeOn(Main).flatMap { ui() }.subscribe { /* unrecoverable exception + crash */ }
note that
subscribe
is
unsafeRunAsync
, whereas
unsafeRynSync
is
blockingFirst
💯 1
d
so would you handle errors within
unsafeRunAsync
?
unsafeRunSync
was the precise reason it was hanging! Got it to work with the async version:
Copy code
IO.fx {
            continueOn(<http://Dispatchers.IO|Dispatchers.IO>)
            val inventory = !requestOperations.getInventory()
            continueOn(Dispatchers.Main)
            inventoryLiveData.value = inventory
        }
            .unsafeRunAsync {
                it.fold(
                    ifLeft = {
                        // handle error
                    },
                    ifRight = {
                        // completed
                    }
                )
            }
🎉 1
r
You can use continue on and arbitrary parMapN inside Fx with your own dispatchers
It's an effect
Anything can go inside IO
👍 1
d
I'm slowly but surely getting the picture!
p
so would you handle errors within
unsafeRunAsync
.handleErrorWith before you run it
and you can do that at any layer
per operation
Copy code
!requestOperations.getInventory()
  .handleError { showErrorUI() }
for the whole thing
Copy code
IO. fx { ... }
  .handleErrorWith { 
    effect(UI) { showErrorUI()  } 
  }