oolong icon indicating copy to clipboard operation
oolong copied to clipboard

Subscription support

Open jcornaz opened this issue 5 years ago • 2 comments
trafficstars

Is your feature request related to a problem? Please describe.

I want to subscribe to some events, that might be external to my system. Example:

  • Get an event every X seconds
  • Subscribe to events from a websocket

Describe the solution you'd like

Since the present library is inspired from elm, I'd find natural to imitate elm's subscription system (in Browser.element).

That could be translated in Kotlin like this:

data class Model(val ticks: Int = 0)
sealed class Msg {
  object Tick : Msg()
}

val subscribe = Subscribe<Model, Msg> { model ->
  every(10.seconds).map { Msg.Tick }
}

// ...

val dispose = Oolong.runtime(
    init,
    update,
    suscribe,
    view,
    render
)

Of course this is only a draft example, and any variation of the API would do.

Describe alternatives you've considered

I think I could start a coroutine from a disposable effect that will call dispatch to fire the messages.

That would however require me to keep an instance of the dispose in my model, so that I can cancel it later.

jcornaz avatar Jul 17 '20 15:07 jcornaz

Actually, after playing a little bit, I think using disposableEffect to start a long running job that fire messages is not so bad.

Maybe all we need is only documentation on how to create/cancel a subscriptions using disposableEffect.

P.S: Here is an adaptation of the code I wrote above, using effects:

data class Model(val ticks: Int = 0)

sealed class Msg {
  object Tick : Msg()
}

fun every(duration: Duration): Effect<Int> = { dispatch ->
  var count = 0
  while (isActive) {
    dispatch(count++)
    delay(duration)
  }
}

val tick = every(10.seconds).map {  Msg.Tick }

val init = { Model() to tick }

// ...

val dispose = Oolong.runtime(
    init,
    update,
    view,
    render
)

jcornaz avatar Jul 28 '20 07:07 jcornaz

Yes, I agree that we need better documentation, recipes, and examples. You're right on track with using disposableEffect for subscriptions that you want to cancel, though. For reference, here's an example of a tick subscription which is very similar to what you already have:

https://github.com/oolong-kt/samples/blob/master/samples/time/core/src/commonMain/kotlin/time/Time.kt#L25

I'll add this to the documentation project. Thanks for the contribution!

pardom avatar Aug 20 '20 01:08 pardom