UDPSocket currently doesn't support receiving messages in bulk, while some operating systems (Linux for example) may support it.
I am proposing to add a way to receive multiple messages at once if the system supports it, potentially via a method of the form:
def receive_bulk(max_messages = 16, max_message_size = 512) : Array(Tuple(String, IPAddress))
end
On systems that do not support bulk retrieval of messages, this method will return an array containing one message everytime.
What are your thoughts and opinions about this ?
We could also add a
def send_bulk(messages : Array(Tuple(String, IPAddress)))
end
Returning array isn't a really good idea, the method can yield a block.
Same perhaps goes for a send_bulk too, it should perhaps be any enumerable that implements each that yield that tuple.
Before going to implementation, let's review the underlying system calls. Do you mean the linux-specific sendmmsg(2) and recvmmsg(2) extensions to sendmsg(2) and recvmsg(2)? There are some issues:
send(2), sendto(2) and recv(2), recvfrom(2).Yes @ysbaddaden, I was planing on using sendmmsg and recvmmsg on the platforms that support it, and default to using the typical send and receive of the UDPSocket on platform that don't support them
Would this work well as a shard?
@wontruefree I could make a shard that inherits absolutely everything from UDP Socket then mostly breach the whole private members of it open to send the system calls, but I honestly think that not being to handle 40k echos in vanilla Crystal using UDP is a shame. It is exactly not following the "Fast as C" part of the philosophy
@yxhuvud we could do it with such enumerable, but it may require more data copies to abstract the contents away, while arrays are convertible to their associated Slice iirc
Messages may be passed as an Array or Enumerable, you must still allocate an Array(LibC::Mmsghdr) to pass to sendmmsg.
Most helpful comment
Returning array isn't a really good idea, the method can yield a block.