Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #57049 > unrolled thread

Weird problem with UDP and gevent

Started byroy@panix.com (Roy Smith)
First post2013-10-18 11:00 -0400
Last post2013-10-19 15:15 +0000
Articles 4 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Weird problem with UDP and gevent roy@panix.com (Roy Smith) - 2013-10-18 11:00 -0400
    Re: Weird problem with UDP and gevent "James Harris" <james.harris.1@gmail.com> - 2013-10-18 18:04 +0100
      Re: Weird problem with UDP and gevent Roy Smith <roy@panix.com> - 2013-10-18 11:44 -0700
      Re: Weird problem with UDP and gevent Grant Edwards <invalid@invalid.invalid> - 2013-10-19 15:15 +0000

#57049 — Weird problem with UDP and gevent

Fromroy@panix.com (Roy Smith)
Date2013-10-18 11:00 -0400
SubjectWeird problem with UDP and gevent
Message-ID<l3riea$82$1@panix2.panix.com>
I'm running:

Ubuntu Precise
Python 2.7.3
django 1.4.5
gunicorn 0.17.4
gevent 1.0dev (rc3)

I haven't been able to pin this down exactly, but it looks like if I
do (inside of a custom logging.Handler subclass):

   	# Paraphrased from the actual code
	remote_addr = ("localhost", 9700)
 	self.socket = socket.socket(type=socket.SOCK_DGRAM)
        payload = "..."
	self.socket.connect(remote_addr)
        self.socket.send(payload)

I get intermittant hangs in the connect() call.  If I rewrite this as:

	remote_addr = ("localhost", 9700)
        self.socket = socket.socket(type=socket.SOCK_DGRAM)
        payload = "..."
        self.socket.sendto(payload, remote_addr)

everything works fine.  Has anybody seen anything like this?  I'm
guessing this is some kind of gevent bug.

My apologies if this is the wrong forum.  The gevent mailing list
appears to be broken (no activity in 3 weeks, no response to
subscription request, post via google groups disappeared into the
void), so I'm trying here.

[toc] | [next] | [standalone]


#57067

From"James Harris" <james.harris.1@gmail.com>
Date2013-10-18 18:04 +0100
Message-ID<l3rpn9$v8u$1@dont-email.me>
In reply to#57049
"Roy Smith" <roy@panix.com> wrote in message 
news:l3riea$82$1@panix2.panix.com...
> I'm running:
>
> Ubuntu Precise
> Python 2.7.3
> django 1.4.5
> gunicorn 0.17.4
> gevent 1.0dev (rc3)
>
> I haven't been able to pin this down exactly, but it looks like if I
> do (inside of a custom logging.Handler subclass):
>
>   # Paraphrased from the actual code
> remote_addr = ("localhost", 9700)
>  self.socket = socket.socket(type=socket.SOCK_DGRAM)
>        payload = "..."
> self.socket.connect(remote_addr)
>        self.socket.send(payload)
>
> I get intermittant hangs in the connect() call.  If I rewrite this as:
>
> remote_addr = ("localhost", 9700)
>        self.socket = socket.socket(type=socket.SOCK_DGRAM)
>        payload = "..."
>        self.socket.sendto(payload, remote_addr)
>
> everything works fine.  Has anybody seen anything like this?  I'm
> guessing this is some kind of gevent bug.

Those are two different things. You would normally use connect() on a 
SOCK_STREAM socket. It requires that the remote endpoint, in this case 
localhost:9700, has an open socket listening for connections. sendto() is 
the right thing to use with SOCK_DGRAM.

James

[toc] | [prev] | [next] | [standalone]


#57071

FromRoy Smith <roy@panix.com>
Date2013-10-18 11:44 -0700
Message-ID<8da951cc-53a8-4756-88dd-759f0dc46ccc@googlegroups.com>
In reply to#57067
On Friday, October 18, 2013 1:04:38 PM UTC-4, James Harris wrote:
> Those are two different things. You would normally use connect() on a 
> SOCK_STREAM socket. It requires that the remote endpoint, in this case 
> localhost:9700, has an open socket listening for connections. sendto() is 
> the right thing to use with SOCK_DGRAM.

You are supposed to be able to call connect() on a UDP socket.  All it does is store the remote address in the kernel socket structure.  Doing connect() followed by a series of send()s is nominally more efficient than doing a series of sendto()s.

I forgot to mention that the connect()/send() code works just fine if I switch my gunicorn config from gevent to sync workers.

[toc] | [prev] | [next] | [standalone]


#57106

FromGrant Edwards <invalid@invalid.invalid>
Date2013-10-19 15:15 +0000
Message-ID<l3u7ls$a1k$1@reader1.panix.com>
In reply to#57067
On 2013-10-18, James Harris <james.harris.1@gmail.com> wrote:
> "Roy Smith" <roy@panix.com> wrote in message 
> news:l3riea$82$1@panix2.panix.com...
>> I'm running:
>>
>> Ubuntu Precise
>> Python 2.7.3
>> django 1.4.5
>> gunicorn 0.17.4
>> gevent 1.0dev (rc3)
>>
>> I haven't been able to pin this down exactly, but it looks like if I
>> do (inside of a custom logging.Handler subclass):
>>
>>   # Paraphrased from the actual code
>> remote_addr = ("localhost", 9700)
>>  self.socket = socket.socket(type=socket.SOCK_DGRAM)
>>        payload = "..."
>> self.socket.connect(remote_addr)
>>        self.socket.send(payload)
>>
>> I get intermittant hangs in the connect() call.  If I rewrite this as:
>>
>> remote_addr = ("localhost", 9700)
>>        self.socket = socket.socket(type=socket.SOCK_DGRAM)
>>        payload = "..."
>>        self.socket.sendto(payload, remote_addr)
>>
>> everything works fine.  Has anybody seen anything like this?  I'm
>> guessing this is some kind of gevent bug.
>
> Those are two different things.

Yes.  They differ in the addresses _from_which_ packets can be
received. In the "connect" example, you will only be able to receive
packets from ("localhost",9700).  In the second example you can
receive packets from any address.  Since the snippets only send
packets not receive packets, they should both behave identically.

> You would normally use connect() on a SOCK_STREAM socket. It requires
> that the remote endpoint, in this case localhost:9700, has an open
> socket listening for connections. sendto() is the right thing to use
> with SOCK_DGRAM.

Either will work.  You can use connect() with a SOCK_DGRAM.  What it
does is 

 1) save the destination address and use it when you call send()

 2) limit the addresses from which packets will be received. 

From the Linux connect(2) man page:

   If the socket sockfd is of type SOCK_DGRAM then addr is the address
   to which datagrams are sent by default, and the only address from
   which datagrams are received.

-- 
Grant

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web