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 Le 16/05/2017 à 17:56, Mark Hamburg a écrit : > 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. > -- 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.
