Discussion:
[elm-discuss] Implementing a protocol on top of WebSocket: should I build a effect module ?
Christophe de Vienne
2017-05-16 14:30:07 UTC
Permalink
Hi everyone,

I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.

I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.

I suspect it would be a lot more natural with an effect module, with
which I could (hopefully) write, in any part of the application:

subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage

or, for req/rep (a pub + a short-living sub expecting a result):

myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply


Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige

Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?

Is there any existing module that does this kind of thing for another
protocol ?

Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Aaron VonderHaar
2017-05-16 15:02:41 UTC
Permalink
Hi, I haven't played much with WebSockets, but I have been building a
protocol on top of HTTP. I haven't yet run into an issue that made me
think to try an effects module.

Instead of having custom subscriptions, my package has an `update` function
that takes any msgs resulting from its commands and returns some
appropriate stuff (in my case, that is an optional output value that the
caller can do something with, and also another Cmd to run).

For the Cmds, I do have to use the Tasks portion of the HTTP API so that I
can compose and chain things together (though I do in the end return a Cmd
for most functions in my protocol's API). For WebSockets, I see there's
http://package.elm-lang.org/packages/elm-lang/websocket/1.0.2/WebSocket-LowLevel
which provides Tasks instead of Cmds, so it's likely you could use that for
what you need.

I don't know if those things will address all the needs of your WebSockets
protocol, but those approaches have worked for what I've been building.
(Sorry, it's not open-source, so can't share the code.)

--Aaron V.

On Tue, May 16, 2017 at 7:30 AM, Christophe de Vienne <
Post by Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-16 15:17:36 UTC
Permalink
Thank you for the feedback.

I am still trying to find a non-effect based API. Did not find anything
satisfying so far.

The WebSocket.LowLevel module is interesting for send batches, but my
main issue is how to associate a custom message translator to each
subscription in a global protocol state.
Post by Aaron VonderHaar
Hi, I haven't played much with WebSockets, but I have been building a
protocol on top of HTTP. I haven't yet run into an issue that made me
think to try an effects module.
Instead of having custom subscriptions, my package has an `update`
function that takes any msgs resulting from its commands and returns
some appropriate stuff (in my case, that is an optional output value
that the caller can do something with, and also another Cmd to run).
For the Cmds, I do have to use the Tasks portion of the HTTP API so that
I can compose and chain things together (though I do in the end return a
Cmd for most functions in my protocol's API). For WebSockets, I see
there's http://package.elm-lang.org/packages/elm-lang/websocket/1.0.2/WebSocket-LowLevel
which provides Tasks instead of Cmds, so it's likely you could use that
for what you need.
I don't know if those things will address all the needs of your
WebSockets protocol, but those approaches have worked for what I've been
building. (Sorry, it's not open-source, so can't share the code.)
--Aaron V.
On Tue, May 16, 2017 at 7:30 AM, Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it,
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-16 15:32:14 UTC
Permalink
Post by Christophe de Vienne
Thank you for the feedback.
I am still trying to find a non-effect based API. Did not find anything
satisfying so far.
The WebSocket.LowLevel module is interesting for send batches, but my
main issue is how to associate a custom message translator to each
subscription in a global protocol state.
Plus the WebSocket module provides very useful behavior I would prefer
not to reimplement.
Post by Christophe de Vienne
Post by Aaron VonderHaar
Hi, I haven't played much with WebSockets, but I have been building a
protocol on top of HTTP. I haven't yet run into an issue that made me
think to try an effects module.
Instead of having custom subscriptions, my package has an `update`
function that takes any msgs resulting from its commands and returns
some appropriate stuff (in my case, that is an optional output value
that the caller can do something with, and also another Cmd to run).
For the Cmds, I do have to use the Tasks portion of the HTTP API so that
I can compose and chain things together (though I do in the end return a
Cmd for most functions in my protocol's API). For WebSockets, I see
there's http://package.elm-lang.org/packages/elm-lang/websocket/1.0.2/WebSocket-LowLevel
which provides Tasks instead of Cmds, so it's likely you could use that
for what you need.
I don't know if those things will address all the needs of your
WebSockets protocol, but those approaches have worked for what I've been
building. (Sorry, it's not open-source, so can't share the code.)
--Aaron V.
On Tue, May 16, 2017 at 7:30 AM, Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it,
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Mark Hamburg
2017-05-16 15:56:44 UTC
Permalink
I've been looking at similar issues for protocol handling.

As I understand it — and I would welcome someone pointing to evidence otherwise — effects modules can't use other effects modules. That means that if you want to use web sockets, you either don't use some of the services that effects modules provide (subscriptions, easy routing for commands) or you build your own effects module possibly cutting and using the low level web sockets module used by the web sockets effects module. (What's the thinking on whether that's a recommended choice? My inference from the name "low level" is "please stay away", but maybe that inference is mistaken.)

If you don't want to go the low-level route, then you need to build something on top of the existing web sockets effects module.

For command-like behavior, this is relatively straightforward. For example, you can change the return value from update functions from ( Model, Cmd Msg ) to ( Model, Operation Msg ) where Operation is a type that mirrors and subsumed Cmd while also allowing your top level code to route requests to your protocol handling module and to route responses back to the rest of your code. In some sense, this is what effects managers are doing. They just do it with linguistic and runtime support so that you don't have to wire things up.

Subscriptions can be handled in the same way. You can replace the subscriptions function call with a call to something like `observations` and get back a similar structure that subsumes regular subscriptions while also allowing your top-level code to route items meant for your "user-mode effects manager" to that manager. At this point, however, you will need to figure out how often to call `observations`. My understanding is that Elm calls this after every update but I don't think the documentation says.

In other words, if you want to build an effects manager like piece of code but don't want to write it as an effects manager — because, for example, you want to use other effects managers — you can do so. You just need to build parallels to the standard Elm infrastructure.

You also need to reconcile yourself if this is concern to the fact that your user mode effects manager will be storing functions in the model to remember how to route responses. If it's any solace, that's what regular effects managers do as well, so I wouldn't feel too bad about it.

But maybe someone can render this whole message moot by saying "just write an effects manager because there is no prohibition on one effects manager using another". Of course, that would also be easier with documentation about how to write an effects manager, but that's a different subject.

Mark
Post by Christophe de Vienne
Post by Christophe de Vienne
Thank you for the feedback.
I am still trying to find a non-effect based API. Did not find anything
satisfying so far.
The WebSocket.LowLevel module is interesting for send batches, but my
main issue is how to associate a custom message translator to each
subscription in a global protocol state.
Plus the WebSocket module provides very useful behavior I would prefer
not to reimplement.
Post by Christophe de Vienne
Post by Aaron VonderHaar
Hi, I haven't played much with WebSockets, but I have been building a
protocol on top of HTTP. I haven't yet run into an issue that made me
think to try an effects module.
Instead of having custom subscriptions, my package has an `update`
function that takes any msgs resulting from its commands and returns
some appropriate stuff (in my case, that is an optional output value
that the caller can do something with, and also another Cmd to run).
For the Cmds, I do have to use the Tasks portion of the HTTP API so that
I can compose and chain things together (though I do in the end return a
Cmd for most functions in my protocol's API). For WebSockets, I see
there's http://package.elm-lang.org/packages/elm-lang/websocket/1.0.2/WebSocket-LowLevel
which provides Tasks instead of Cmds, so it's likely you could use that
for what you need.
I don't know if those things will address all the needs of your
WebSockets protocol, but those approaches have worked for what I've been
building. (Sorry, it's not open-source, so can't share the code.)
--Aaron V.
On Tue, May 16, 2017 at 7:30 AM, Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it,
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-16 16:05:49 UTC
Permalink
Hi Mark,

What you describe as an alternative to an effect module is more or less
what I am building right now (well, I am attempting to anyway), which is
encouraging :-) thanks for the feedback !

The question of effect modules using other effect modules also came up
when reading some effect module source code. It would be nice having a
definitive answer to it.

Christophe
Post by Mark Hamburg
I've been looking at similar issues for protocol handling.
As I understand it — and I would welcome someone pointing to evidence otherwise — effects modules can't use other effects modules. That means that if you want to use web sockets, you either don't use some of the services that effects modules provide (subscriptions, easy routing for commands) or you build your own effects module possibly cutting and using the low level web sockets module used by the web sockets effects module. (What's the thinking on whether that's a recommended choice? My inference from the name "low level" is "please stay away", but maybe that inference is mistaken.)
If you don't want to go the low-level route, then you need to build something on top of the existing web sockets effects module.
For command-like behavior, this is relatively straightforward. For example, you can change the return value from update functions from ( Model, Cmd Msg ) to ( Model, Operation Msg ) where Operation is a type that mirrors and subsumed Cmd while also allowing your top level code to route requests to your protocol handling module and to route responses back to the rest of your code. In some sense, this is what effects managers are doing. They just do it with linguistic and runtime support so that you don't have to wire things up.
Subscriptions can be handled in the same way. You can replace the subscriptions function call with a call to something like `observations` and get back a similar structure that subsumes regular subscriptions while also allowing your top-level code to route items meant for your "user-mode effects manager" to that manager. At this point, however, you will need to figure out how often to call `observations`. My understanding is that Elm calls this after every update but I don't think the documentation says.
In other words, if you want to build an effects manager like piece of code but don't want to write it as an effects manager — because, for example, you want to use other effects managers — you can do so. You just need to build parallels to the standard Elm infrastructure.
You also need to reconcile yourself if this is concern to the fact that your user mode effects manager will be storing functions in the model to remember how to route responses. If it's any solace, that's what regular effects managers do as well, so I wouldn't feel too bad about it.
But maybe someone can render this whole message moot by saying "just write an effects manager because there is no prohibition on one effects manager using another". Of course, that would also be easier with documentation about how to write an effects manager, but that's a different subject.
Mark
Post by Christophe de Vienne
Post by Christophe de Vienne
Thank you for the feedback.
I am still trying to find a non-effect based API. Did not find anything
satisfying so far.
The WebSocket.LowLevel module is interesting for send batches, but my
main issue is how to associate a custom message translator to each
subscription in a global protocol state.
Plus the WebSocket module provides very useful behavior I would prefer
not to reimplement.
Post by Christophe de Vienne
Post by Aaron VonderHaar
Hi, I haven't played much with WebSockets, but I have been building a
protocol on top of HTTP. I haven't yet run into an issue that made me
think to try an effects module.
Instead of having custom subscriptions, my package has an `update`
function that takes any msgs resulting from its commands and returns
some appropriate stuff (in my case, that is an optional output value
that the caller can do something with, and also another Cmd to run).
For the Cmds, I do have to use the Tasks portion of the HTTP API so that
I can compose and chain things together (though I do in the end return a
Cmd for most functions in my protocol's API). For WebSockets, I see
there's http://package.elm-lang.org/packages/elm-lang/websocket/1.0.2/WebSocket-LowLevel
which provides Tasks instead of Cmds, so it's likely you could use that
for what you need.
I don't know if those things will address all the needs of your
WebSockets protocol, but those approaches have worked for what I've been
building. (Sorry, it's not open-source, so can't share the code.)
--Aaron V.
On Tue, May 16, 2017 at 7:30 AM, Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it,
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Aaron VonderHaar
2017-05-16 16:59:46 UTC
Permalink
I think another question worth asking is what Tasks should to official
WebSocket package expose to be useful to protocol module authors?

Originally, someone was going to implement a Phoenix channels package on
top of websockets as a real-world example of a websockets protocol, but
afaik that never needed up happening. So your package may be the first to
try to modularize a websockets protocol. I expect you'll probably run into
things that could be motivating use cases for changes/additions to the
websockets package.
Post by Christophe de Vienne
Post by Christophe de Vienne
Thank you for the feedback.
I am still trying to find a non-effect based API. Did not find anything
satisfying so far.
The WebSocket.LowLevel module is interesting for send batches, but my
main issue is how to associate a custom message translator to each
subscription in a global protocol state.
Plus the WebSocket module provides very useful behavior I would prefer
not to reimplement.
Post by Christophe de Vienne
Post by Aaron VonderHaar
Hi, I haven't played much with WebSockets, but I have been building a
protocol on top of HTTP. I haven't yet run into an issue that made me
think to try an effects module.
Instead of having custom subscriptions, my package has an `update`
function that takes any msgs resulting from its commands and returns
some appropriate stuff (in my case, that is an optional output value
that the caller can do something with, and also another Cmd to run).
For the Cmds, I do have to use the Tasks portion of the HTTP API so that
I can compose and chain things together (though I do in the end return a
Cmd for most functions in my protocol's API). For WebSockets, I see
there's http://package.elm-lang.org/packages/elm-lang/websocket/1.0.
2/WebSocket-LowLevel
Post by Christophe de Vienne
Post by Aaron VonderHaar
which provides Tasks instead of Cmds, so it's likely you could use that
for what you need.
I don't know if those things will address all the needs of your
WebSockets protocol, but those approaches have worked for what I've been
building. (Sorry, it's not open-source, so can't share the code.)
--Aaron V.
On Tue, May 16, 2017 at 7:30 AM, Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io)
protocol
Post by Christophe de Vienne
Post by Aaron VonderHaar
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would
like
Post by Christophe de Vienne
Post by Aaron VonderHaar
each subscription to generate custom messages for the component
which
Post by Christophe de Vienne
Post by Aaron VonderHaar
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or
3
Post by Christophe de Vienne
Post by Aaron VonderHaar
messages through the websocket, in the right order, but
WebSocket.send
Post by Christophe de Vienne
Post by Aaron VonderHaar
returns a Cmd. So I have to concat the 3 commands in 1 message,
which
Post by Christophe de Vienne
Post by Aaron VonderHaar
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with
them ?
Post by Christophe de Vienne
Post by Aaron VonderHaar
Is there any existing module that does this kind of thing for
another
Post by Christophe de Vienne
Post by Aaron VonderHaar
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it,
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Oliver Searle-Barnes
2017-05-16 23:38:59 UTC
Permalink
You might find https://github.com/saschatimme/elm-phoenix useful to look
at, it's an effects manager phoenix channels built on top of the websocket
effects manager.
Post by Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Mark Hamburg
2017-05-17 04:01:37 UTC
Permalink
The Phoenix code is interesting but it is not an example of one effects manager using another. It bypasses the web socket effects manager and talks to the low level API.

Mark
You might find https://github.com/saschatimme/elm-phoenix useful to look at, it's an effects manager phoenix channels built on top of the websocket effects manager.
Post by Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Wojciech Piekutowski
2017-05-17 06:24:02 UTC
Permalink
There's also https://github.com/fbonetti/elm-phoenix-socket/. It doesn't
use an effect manager, but apparently because of that doesn't notify about
disconnection.
Post by Oliver Searle-Barnes
You might find https://github.com/saschatimme/elm-phoenix useful to look
at, it's an effects manager phoenix channels built on top of the websocket
effects manager.
Post by Christophe de Vienne
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-17 07:15:28 UTC
Permalink
Post by Wojciech Piekutowski
There's also https://github.com/fbonetti/elm-phoenix-socket/. It doesn't
use an effect manager, but apparently because of that doesn't notify
about disconnection.
Very interesting. One limit I see is that only one type of Msg can be
emitted by the subscription, which forces to handle all the
subscriptions in the same component.

In my case, I need the subscriptions to be initialized and used in
various components. I think I found a way to do that, I will put it on
github soon.

Another limit I an hitting with a non-effect module, and for which I see
no solution, is when several messages arrive in a single websocket
message. In this case we should emit several custom message for one
incoming websocket message.

Fortunalely, I can temper with the server and make sure one nats message
comes in as a single websocket message, which workaround the issue.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-17 16:02:43 UTC
Permalink
Post by Christophe de Vienne
Post by Wojciech Piekutowski
There's also https://github.com/fbonetti/elm-phoenix-socket/. It doesn't
use an effect manager, but apparently because of that doesn't notify
about disconnection.
Very interesting. One limit I see is that only one type of Msg can be
emitted by the subscription, which forces to handle all the
subscriptions in the same component.
In my case, I need the subscriptions to be initialized and used in
various components. I think I found a way to do that, I will put it on
github soon.
Another limit I an hitting with a non-effect module, and for which I see
no solution, is when several messages arrive in a single websocket
message. In this case we should emit several custom message for one
incoming websocket message.
Fortunalely, I can temper with the server and make sure one nats message
comes in as a single websocket message, which workaround the issue.
So, I have a first version of a Nats module, which handles properly the
subscriptions (at least as I wanted it to).

https://github.com/orus-io/elm-nats

It is requires a nats/websocket gateway I wrote too
(https://github.com/orus-io/nats-websocket-gw)

The main thing that bothers me is that I will need to pass the
Nats.State to every update function because subscribing requires an
update of the state... And I see no way to avoid that except using an
effect module.

There are plenty improvements to do (starting with the documentation),
but some feedback would be really appreciated.

Thanks for all the helpfull response to my OP !
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Rupert Smith' via Elm Discuss
2017-05-18 08:46:34 UTC
Permalink
Post by Christophe de Vienne
The main thing that bothers me is that I will need to pass the
Nats.State to every update function because subscribing requires an
update of the state... And I see no way to avoid that except using an
effect module.
So you would rather that your Nats module kept its own state 'private' and
lets users of it send it a message asking to subscribe?

Suppose your code has 3 update functions and is structured like this:

Main (top-level update)
- Nats (updates Nats State as websocket conversation progresses)
- MyFunkyApp (does something cool. Needs to subscribe to Nats)

The TEA pattern that you could use to do this, whilst keeping the Nats
state private, is to use an 'out message' from MyFunkyApp. Then have some
routing in Main, that passes the subscriptions requests to Nats, where Nats
can update its State in private.

It can be a lot of boilerplate if you have lots of modules using Nats, so I
can see why the effects module approach is appealing.

===

I was eating breakfast this morning when it occurred to me that I may have
a solution for you; it is an effects module:

https://github.com/rupertlssmith/elmq

If we divide your Nats implementation into two independant (orthogonal)
parts - there is the websockets part, and there is a part relating to how
you plumb this re-usable protocol module into an Elm application. The
'elmq' effects module could solve the second part for you. This would mean
that you don't need to write your own effects module for this specific
problem as the concept has already been captured by the elmq effects module.

===

Here is an example of using elmq. Authentication is a very common component
of applications and I also felt that it was likely that many modules in my
applications would need to interact with authentication. In particular, I
have quite a few Json web services over HTTP - at any time one of them may
get back a 403 or a 401 and will then need to update the auth state to say
that we are not currently authenticated.

To avoid all the 'out message' plumbing that would require, I built my auth
module on top of elmq.

It provides an API, that stuffs event messages onto elmq channels:

https://github.com/rupertlssmith/elm-auth/blob/master/src/Auth.elm

And the AuthController is then able to subscribe to these messages, and
privately update its state:

https://github.com/rupertlssmith/elm-auth/blob/master/src/AuthController.elm#L228

So you can see, it is very easy for a module to import the Auth API and use
it, without having to worry about the plumbing needed to update the
authentication state.

===

The elmq module was lifted from original code here:
https://github.com/gdotdesign/elm-ui

One limitation of it is that you can only pass the primitive types or a
Json.Encode.Value. Anything else you must provide an Encoder/Decoder for.

See the readme for elmq for some discussion points around how its API could
be evolved. I would be very interested to hear if you think your use case
fits it, or if you think it needs adapted a little to cater for your need?
Would also be very happy to take suggestions on board and improve it.

It is not an official effects module, so you must install it with
elm-github-install.

If it is useful to you, it might be time to consider making a proposal on
elm-dev to push it towards becoming an official effects module. I have
considered this before, but was not sure if it would be well received or
not - its certainly quite a different way of doing things to the TEA
approach. Also as Elm is single threaded, and this is really an
asynchronous messaging model (like JMS for Java), does it make sense as a
programming model for Elm? On the other hand, its very useful, so why not.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-18 10:04:01 UTC
Permalink
This night I found a way to avoid pushing the nats State to all the
components: now I just have them return NatsCmd along with their model
and normal commands, which is what you describe in the first part of
your email (I am still working on it).

It makes the API a lot nicer, although the root component still has to
apply those NatsCmd to the nats State (which is not too bad compared to
before.

As for the effect-module approach, I think I will insist on using a
non-effect module until I hit some blocking issues solvable only with a
effect module, like how to both dispatch a custom message and update my
nats State in a single update, which would be needed when a subscription
needs to be removed (after a auto-unsub).

I will definitely have a look to elmq, thanks for pointing it out!
Post by Christophe de Vienne
The main thing that bothers me is that I will need to pass the
Nats.State to every update function because subscribing requires an
update of the state... And I see no way to avoid that except using an
effect module.
So you would rather that your Nats module kept its own state 'private'
and lets users of it send it a message asking to subscribe?
Main (top-level update)
- Nats (updates Nats State as websocket conversation progresses)
- MyFunkyApp (does something cool. Needs to subscribe to Nats)
The TEA pattern that you could use to do this, whilst keeping the Nats
state private, is to use an 'out message' from MyFunkyApp. Then have
some routing in Main, that passes the subscriptions requests to Nats,
where Nats can update its State in private.
It can be a lot of boilerplate if you have lots of modules using Nats,
so I can see why the effects module approach is appealing.
===
I was eating breakfast this morning when it occurred to me that I may
https://github.com/rupertlssmith/elmq
If we divide your Nats implementation into two independant (orthogonal)
parts - there is the websockets part, and there is a part relating to
how you plumb this re-usable protocol module into an Elm application.
The 'elmq' effects module could solve the second part for you. This
would mean that you don't need to write your own effects module for this
specific problem as the concept has already been captured by the elmq
effects module.
===
Here is an example of using elmq. Authentication is a very common
component of applications and I also felt that it was likely that many
modules in my applications would need to interact with authentication.
In particular, I have quite a few Json web services over HTTP - at any
time one of them may get back a 403 or a 401 and will then need to
update the auth state to say that we are not currently authenticated.
To avoid all the 'out message' plumbing that would require, I built my
auth module on top of elmq.
https://github.com/rupertlssmith/elm-auth/blob/master/src/Auth.elm
And the AuthController is then able to subscribe to these messages, and
https://github.com/rupertlssmith/elm-auth/blob/master/src/AuthController.elm#L228
So you can see, it is very easy for a module to import the Auth API and
use it, without having to worry about the plumbing needed to update the
authentication state.
===
https://github.com/gdotdesign/elm-ui
One limitation of it is that you can only pass the primitive types or a
Json.Encode.Value. Anything else you must provide an Encoder/Decoder for.
See the readme for elmq for some discussion points around how its API
could be evolved. I would be very interested to hear if you think your
use case fits it, or if you think it needs adapted a little to cater for
your need? Would also be very happy to take suggestions on board and
improve it.
It is not an official effects module, so you must install it with
elm-github-install.
If it is useful to you, it might be time to consider making a proposal
on elm-dev to push it towards becoming an official effects module. I
have considered this before, but was not sure if it would be well
received or not - its certainly quite a different way of doing things to
the TEA approach. Also as Elm is single threaded, and this is really an
asynchronous messaging model (like JMS for Java), does it make sense as
a programming model for Elm? On the other hand, its very useful, so why not.
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Christophe de Vienne
2017-05-17 07:20:34 UTC
Permalink
A nice place to start with if I want to go down the effect-module road.
Although as Mark said it rely on the WebSocket.LowLevel module, which
imply extra complexity in the implementation.

The resulting API looks a lot clearer and more natural than the other
phoenix implementation, which is a big bonus.
Post by Oliver Searle-Barnes
You might find https://github.com/saschatimme/elm-phoenix useful to look
at, it's an effects manager phoenix channels built on top of the
websocket effects manager.
Hi everyone,
I am attempting to implement the pub/sub NATS (https://nats.io) protocol
on top of the WebSocket API as a TEA component.
I have a hard time finding an API for subscriptions: for each
subscription some context must be kept, a unique subscription ID
generated and in some case a unique reply subject too, and I would like
each subscription to generate custom messages for the component which
made it.
I suspect it would be a lot more natural with an effect module, with
subscriptions : Model -> Sub Msg
subscriptions model =
Nats.Subscribe model.endpoint "some.subject" MyMessage
myrequest : Model -> Cmd Msg
myrequest model =
Nats.request model.endpoint "a.request.subject" MyReply
Another difficulty I have is that in some cases I need to send 2 or 3
messages through the websocket, in the right order, but WebSocket.send
returns a Cmd. So I have to concat the 3 commands in 1 message, which
works but oblige
Am I wrong being tempted by using an effect module for this kind of module ?
If so how can I mimick such an API with a TEA approach ?
If not is there any documentation I can read to get familiar with them ?
Is there any existing module that does this kind of thing for another
protocol ?
Thanks!
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google
Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send
For more options, visit https://groups.google.com/d/optout.
--
Christophe de Vienne
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...