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 > On May 16, 2017, at 8:32 AM, Christophe de Vienne <[email protected]> > wrote: > > > >> Le 16/05/2017 à 17:17, Christophe de Vienne a écrit : >> 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. > >> >>> Le 16/05/2017 à 17:02, Aaron VonderHaar a écrit : >>> 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 >>> <[email protected] <mailto:[email protected]>> wrote: >>> >>> 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 [email protected] >>> <mailto:elm-discuss%[email protected]>. >>> 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 >>> an email to [email protected] >>> <mailto:[email protected]>. >>> 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 [email protected]. > 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
