Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to map a Sub message to multiple ones #274

Open
Iltotore opened this issue Aug 4, 2024 · 4 comments
Open

Add a way to map a Sub message to multiple ones #274

Iltotore opened this issue Aug 4, 2024 · 4 comments
Labels
under consideration The issue needs time to mature and ripen in the minds of those considering it. workaround

Comments

@Iltotore
Copy link

Iltotore commented Aug 4, 2024

Currently, it is not possible to map a value produced by a Sub to multiple ones, which could be useful in many cases.

Here is my own use case: I am making a Scala wrapper for Pokemon Showdown's API. The messages sent by the server look like this:

>roomid
message1
message2
...

in a single text frame.

WebSocket#subscribe returns a Sub[F, WebSocketEvent] (excluding the mapping function asked in parameter) and I'd like to be able to turn this WebSocketEvent into multiple ServerMessage (from my API).

My first intuition was to use flatMap+Sub.combine but the former method does not exist and looking at the architecture of Sub, I'm not sure if it is possible to implement it cleanly.

Another approach would be to introduce a Sub[F, A]#mapMultiple (or similar name) taking a A => Iterable[B] and returning a Sub[F, B].

@davesmith00000
Copy link
Member

Hi!

Yes, so currently I guess what you'd need to do is make a Msg that contains a list of the sub messages and then on model update, either fire them off individually or process the batch.

the former method does not exist

Indeed, Cmd's and Sub's are not monadic.

Sub's making other subs sounds dubious. What you want - I think - is not more sub's but a way to return multiple messages from your sub? Have a read that right?

@Iltotore
Copy link
Author

Yes, so currently I guess what you'd need to do is make a Msg that contains a list of the sub messages and then on model update, either fire them off individually or process the batch.

Yes this is my current workaround althrough I'd like this "implementation detail" to not leak.

a way to return multiple messages from your sub? Have a read that right?

Yes. A way to map a single message produced by a Sub to multiple ones.

In my use case, I have a Sub[F, WebSocketFrame] that I'd like to map to a Sub[F, ServerMessage] potentially returning multiple ServerMessage for one WebSocketFrame.

@davesmith00000
Copy link
Member

Great, thanks.

You can map sub's already to convert one message type to another, so maybe, if instead of returning an Option[Msg] we just return a List[Msg], we might be able to modify things to allow one result to produce many messages.

I'll look into it as soon as I'm back in Tyrian mode.. 😅

@davesmith00000 davesmith00000 added workaround under consideration The issue needs time to mature and ripen in the minds of those considering it. labels Aug 24, 2024
@davesmith00000
Copy link
Member

I've had another think about this, and also tried implementing it and my conclusion is... I need to think about it a bit more. 🙂

The use case here is quite specific:
When using a websocket (but it could be http too), you can receive several messages in a single payload/bundle from the server, and you like to chop them up, and send them out to be processed individually. Fair enough. However I feel like this is a corner case.

The general case is that something happened, or it didn't, and if it did, please let the main app logic know so that it can be dealt with.

Now.... Option is a special case of List, so maybe I'm splitting hairs, but right now it feels like Option better represents the general case, and dissuades people from trying to be too clever in their subs.

The workaround, is to put the many-part server messages into a single Msg, and let the update function decide what to do next, which could either be to just get on with the processing of the batch immediately, or split into more Msgs and send them round but emitting them from Cmds. Which of those is the correct approach might be use-case dependant, but I'm incline to prefer updating the batch immediately, because what benefit is there of going round the loop again individually (even if Sub could produce many messages - what is the benefit?).

Sometimes I myself make issues that express some frustration with the APIs while I'm trying to do something, and then close them once I've stopped to think about the implications of the change and what it all means. I'm not saying this is definitely one of those times, but it feels a bit like it might be.

More thought needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
under consideration The issue needs time to mature and ripen in the minds of those considering it. workaround
Projects
None yet
Development

No branches or pull requests

2 participants