Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gevent, sockets and synchronisation

I have multiple greenlets sending on a common socket. Is it guaranteed that each package sent via socket.sendall is well separated or do I have to acquire a lock before each call to sendall.

So I want to prevent the following scenario:

  • g1 sends ABCD
  • g2 sends 1234
  • received data is mixed up, for example AB1234CD
  • expected is either ABCD1234 or 1234ABCD

Update

After a look at the sourcecode I think this scenario cannot happen. But I have to use a lock because g1 or g2 can crash on the sendall. Can someone confirm this?

like image 475
schlamar Avatar asked Nov 04 '22 09:11

schlamar


1 Answers

I did some tests with a high latency / low bandwitch interface and got the expected error.

  • Simulation of slow interface: https://superuser.com/a/147434
  • Test script: https://gist.github.com/4249827/6779dfbebc255e81252e9b29c94add98c5771669

This resulted (as expected) in the following error:

AssertionError: This event is already used by another greenlet: (<Greenlet 
at 0x7f3e758722d0: <bound method socket.sendall of <socket at 0x7f3e7587719
0 fileno=8 sock=127.0.0.1:1234 peer=127.0.0.1:51042>>('11111111111111111111
11111111111111111111111111111)>, timeout('timed out',))

Here is the fixed test script with a gevent.coros.RLock which doesn't yield this error: https://gist.github.com/4249827/7f02f805331eda4091ae0b39dfea4b102cdba2fa

like image 158
schlamar Avatar answered Nov 12 '22 11:11

schlamar