[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-09-26 Thread Malversán

New submission from Malversán :

Currently the BaseEventLoop class in asyncio has explicit checks to raise 
ValueError when creating a connection if the socket argument has a type other 
than SOCK_STREAM:
.create_connection()
.create_server()

This is also applicable for class _UnixSelectorEventLoop:
.create_unix_connection()
.create_unix_server()

But the fact is that it actually supports other socket types, like 
SOCK_SEQPACKET for example.

Currently you can test this by dirty-hacking the socket class "type" property 
to momentarily trick the event loop into thinking that any socket is of 
SOCK_STREAM type.


# First create an AF_UNIX, SOCK_SEQPACKET socket.
sock = socket.socket(socket.AddressFamily.AF_UNIX, 
socket.SocketKind.SOCK_SEQ_PACKET)
sock.connect(path)

params = { "sock" : sock, "protocol_factory" : lambda: protocol }

# Now do the trick.
hack = (params["sock"].type != socket.SocketKind.SOCK_STREAM)

if hack:
# Substitute class property getter with fixed value getter.
socket_property = socket.socket.type
socket.socket.type = property(lambda self: socket.SocketKind.SOCK_STREAM, 
None, None,)

# Use the socket normally to create connection and run the event loop.
loop = asyncio.new_event_loop()
coroutine = loop.create_unix_connection(**params)# It also works with 
.create_connection()
transport, protocol = loop.run_until_complete(coroutine)

# Revert the trick.
if hack:
# Restore class property getter.
socket.socket.type = socket_property


As dirty as it looks, this works flawlessy. It just tricks the event loop 
.create_connection() call to bypass the explicit check of using a SOCK_STREAM 
socket. This done, THE EVENT LOOP SUPPORTS SOCK_SEQPACKET PERFECTLY.

This is the solution I'm currently using to communicate an application with a 
local daemon, but I would really prefer to have the SOCK_SEQPACKET support 
allowed into the event loop itself. Having in mind that it simply works with 
other socket types, I find that limiting the use of the event loop with an 
explicit SOCK_STREAM-only check is somehow artificial and unrealistic.

Thanks in advance for your attention.

--
components: asyncio
messages: 353296
nosy: asvetlov, malversan, yselivanov
priority: normal
severity: normal
status: open
title: Asyncio BaseEventLoop can support socket types other than SOCK_STREAM
type: enhancement
versions: Python 3.5, Python 3.6, Python 3.7, Python 3.8, Python 3.9

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-09-26 Thread Malversán

Malversán  added the comment:

Certainly I have only tested it with SOCK_SEQPACKET, but apparently no one has 
ever tested this before with a socket type other than SOCK_STREAM. It may be 
worth to consider the possibility that the current asyncio implementation may 
also support some other SocketKind sockets:
- SOCK_SEQPACKET (tested)
- SOCK_DGRAM
- SOCK_RAW
- SOCK_RDM

I agree this is an enhancement to incorporate in future releases. I do not 
expect previous versions to be patched.

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-09-26 Thread Malversán

Malversán  added the comment:

In the past it took me two days to analyze asyncio code, to think up and 
integrate the hack I´m using for this. But I´m not kidding when I tell you that 
it took me two years to find a while to come here and properly report it. I'm 
sorry, but I never have time to dedicate to other projects (I wish I could).

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-09-26 Thread Malversán

Malversán  added the comment:

I'm sorry to read that. I thought the report could be enough to reach whoever 
put that SOCK_STREAM-only checks and ask him why, when the library actually 
works well also with other socket types.

If I ever find enough time to dive into the CPython repository I will come back 
here, but given my work load I would not count on it. Anyway, as long as the 
issue remais opened I'm confident this will be eventually fixed.

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-11-04 Thread Malversán

Malversán  added the comment:

It has a certain logic to recommend recvmsg() in place of recv(), as 
SOCK_SEQ_PACKET is characterized by transmitting entire messages only. But it 
has to be noted that my current hack (described above) is working for 
SOCK_SEQ_PACKET sockets with no modification of the asyncio underlying reading 
logic.

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-11-04 Thread Malversán

Malversán  added the comment:

I do not have the answer about getting message boundaries at lower levels, but 
from a high-level point of view SOCK_SEQ_PACKET gives atomic reads, with no 
need to check for message boundaries yourself. Every time you read from a 
SOCK_SEQ_PACKET socket you get an entire message. That is the main difference 
with SOCK_STREAM, as far as I know.

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-11-04 Thread Malversán

Malversán  added the comment:

In my scenario that buffer overrun never happens, maybe because I use messages 
that are not big enough to overflow the default recv() buffer size.

But I think I can confirm that multiple messages are never received in an 
atomic read, even if they are being issued intensively in short millisecond 
intervals. Even more, I think there is a recvmmsg() call specific for that 
purpose if you want to receive multiple reads at once.

As I said I do not have the answers, I rely on the high-level definitions and 
have little knowledge about how it works at low level.

But I think your question may be extended also to recvmsg(). What is its 
behaviour if it fills all the passed iovec structs?

Probably an answer can be found where you found the recommendation of using 
recvmsg() over recv(). There should be a reason for that recommendation.

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2019-11-05 Thread Malversán

Malversán  added the comment:

I agree. Your question about potential message size overflow should be tested 
(either for recv() and recvmsg()).

Could you please link the resource where you found the recommendation of using 
recvmsg() over recv() for SOCK_SEQ_PACKET?

--

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38285] Asyncio BaseEventLoop can support socket types other than SOCK_STREAM

2021-01-05 Thread Malversán

Malversán  added the comment:

That means the core code also works for SOCK_RAW sockets. It's only limited by 
explicit socket type checks at a higher level.

As a curious note (not related to the issue), I'm also using the SOCK_SEQPACKET 
connection created with BaseEventLoop to access a custom daemon related to BLE 
functionality.

--
versions: +Python 3.10 -Python 3.9

___
Python tracker 
<https://bugs.python.org/issue38285>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com