-
-
Notifications
You must be signed in to change notification settings - Fork 41
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
Selecting records with more than one "tag" element #28
Comments
It's tricky- adding another clause for the second element would result in a performance hit, and selectors are already slower than Erlang receives. Selectors will be used in the hot path for Gleam OTP applications so performance is important here. Do you have thoughts on how it might be implemented? More specifically, could you expand upon the use case and how you'd like to use this new selector? There could be another solution for working with sockets. |
So in other words, it's all speculative 😄 I'm not yet sure why exactly one would want to selectively receive messages about specific sockets (other than defensive programming, and that can be done in other ways). It just is a thing you technically can do with the The context is that I'm writing myself a low-level As far as the shape of that solution, I'm not really sure. It feels like there should be an "escape hatch" (even if you have to write some Erlang) for when you want to receive some non-Gleam messages with potentially any shape, but still take advantage of Actors and Subjects. Maybe this is possible already and I just haven't figured it out yet. But, as I said, the use cases are speculative anyway. |
I'd love to be able to do this, but I've not worked out how this might be implemented yet unfortunately. |
Yeah, it seems tricky when there's no way to directly write the |
It would be a lot more complex, but we could generate an Erlang module at runtime that has a receive function. It would also make creation of a selector a more expensive operation. This library is a good reference for how this could be done: https://github.com/rabbitmq/horus/ |
I've come across another case where the current "selector" functions don't do well, namely {'DOWN', MonitorRef, socket, Object, Info} Even if a |
We have a special case specifically for process down messages, we could expand it for sockets also. {'DOWN', Ref, Kind, Downed, Reason} when is_map_key({Kind, Ref}, Handlers) ->
Fn = maps:get({Kind, Ref}, Handlers),
{ok, Fn(Downed, Reason)}; |
Yeah, though I suppose there would need to be an API for specifying the Kind and Ref directly rather than the layer of abstraction |
I'd stick with the existing design and have a function for each kind of down message. I don't think there's much in common between ports and processes so we don't need to abstract over them. |
Hm, so you think this library should have a |
We'll include a socket module with a definition of a socket type and a monitor function for that. We originally had this for processes and ports, though only the processes one survived the redesign of the Erlang and OTP packages. I should probably bring that back to this package also. |
Ah, I see. To me it feels a bit odd to include an external type (socket) in the library that no function in the library actually produces; and also as a socket library implementer, that a tiny part of that library (monitors) would live in
That way Either way, I would be able to implement this, so let me know if you would like it 🙂 |
This library is intended to provide type definitions for all of the core Erlang data types, so it would include sockets. Slightly odd, but that's just the nature of Erlang and how embedded networked stuff is into the language itself. I don't think that function design would be ideal as there's only 3 types of down, but that API suggests there is an unlimited amount. We want to avoid dynamically typed APIs where practical, and I think we can cover 3 happily. We'd need functions to convert the references even with that API so it would produce more functions rather than fewer, and the call sites would have more boilerplate to work with the untyped data. Do you have a use case for selecting from a specific socket? Generally anything in core should be added in response to real world requirements as we may make incorrect assumptions if predicting usage. |
Makes sense to me.
Nothing that's otherwise impossible, so I will save it for when my library is more developed (assuming it gets there) 🙂 |
The Erlang
socket
module has a "nowait" mode for some functions which, instead of waiting for something to happen (like receiving data), returns immediately and later sends a message letting the caller know when they should try again. The format of this message is{'$socket', Socket, T, X}
, where T is an atom indicating the type of message and X a type-specific payload.If you want a Gleam selector that selects all such "socket messages", that is easy enough:
But I don't think there is currently a way to select only messages related to a specific socket, as it would require treating the first two elements as fixed-value "tags", and
selecting_recordX
only uses the first element.I will say, I don't have a concrete use case for this yet — a process handling multiple sockets would probably want to receive messages for all of them, and a process handling a single socket could just panic if the
Socket
is not what it expects. But it seems like a notable limitation in general, since there is no lower-level API that lets you build arbitrarily-"shaped" selectors. Is that something you've considered? Are there other cases where it would be useful? (selecting_trapped_exits
might be one)The text was updated successfully, but these errors were encountered: