Skip to content

Instantly share code, notes, and snippets.

@turicas
Created June 3, 2012 07:18
Show Gist options
  • Select an option

  • Save turicas/2862393 to your computer and use it in GitHub Desktop.

Select an option

Save turicas/2862393 to your computer and use it in GitHub Desktop.
Bug in pyzmq

This bug is really bizarre: I'm doing some operations inside a class and received a "core dumped" (the process is killed) when trying to destroy the context. But when I do the same operations outside the class, the error simply does not happen!

I can reproduce the bug with two scripts:

  • server.py: creates a context, creates and binds to one zmq.REP socket and start a main loop in which it receives and answers requests (using recv_json and send_json). When receives SIGINT (KeyboardInterrupt), destroy the context and exit.
  • client.py: creates a context, starts a process to run server.py (using subprocess.Popen), connects to server's socket, send/recv a JSON, destroys its context and finishes server's process sending a SIGINT.

I've implemented another version of client.py without using a class (client_without_class.py) but doing the same things and the error simply does not happen! The output for the two implementations is shown below:

$ python client_without_class.py 
Creating client
Sending/receiving JSON
Destroying client's context
Finishing server's process

$ python client.py 
Creating client
Sending/receiving JSON
Destroying client's context
File exists (epoll.cpp:69)
Aborted (core dumped)

System information:

  • zmq.__version__ = '2.1.11'
  • Python version = 2.7.3
  • OS = Ubuntu 12.04 LTS
#!/usr/bin/env python
# coding: utf-8
from signal import SIGINT, SIGKILL
from time import sleep
from subprocess import Popen, PIPE
import shlex
import zmq
time_to_sleep = 0.15
class Client():
def __init__(self):
self.context = zmq.Context()
self.start_server_process()
def start_server_process(self):
self.server = Popen(shlex.split('python server.py'),
stdin=PIPE, stdout=PIPE, stderr=PIPE)
for line in self.server.stdout.readline():
if 'main loop' in line:
break
def end_server_process(self):
self.server.send_signal(SIGINT)
sleep(time_to_sleep)
self.server.send_signal(SIGKILL)
self.server.wait()
def send_and_receive_json(self):
api = self.context.socket(zmq.REQ)
api.connect('tcp://localhost:5555')
cmd = {'command': 'add job', 'worker': 'test', 'document': 'eggs'}
api.send_json(cmd)
sleep(time_to_sleep)
try:
message = api.recv_json(zmq.NOBLOCK)
except zmq.ZMQError:
pass
print 'Creating client'
client = Client()
print 'Sending/receiving JSON'
client.send_and_receive_json()
print "Destroying client's context"
client.context.destroy()
print "Finishing server's process"
client.end_server_process()
#!/usr/bin/env python
# coding: utf-8
from signal import SIGINT, SIGKILL
from time import sleep
from subprocess import Popen, PIPE
import shlex
import zmq
time_to_sleep = 0.15
print 'Creating client'
context = zmq.Context()
server = Popen(shlex.split('python server.py'),
stdin=PIPE, stdout=PIPE, stderr=PIPE)
for line in server.stdout.readline():
if 'main loop' in line:
break
print 'Sending/receiving JSON'
api = context.socket(zmq.REQ)
api.connect('tcp://localhost:5555')
cmd = {'command': 'add job', 'worker': 'test', 'document': 'eggs'}
api.send_json(cmd)
sleep(time_to_sleep)
try:
message = api.recv_json(zmq.NOBLOCK)
except zmq.ZMQError:
pass
print "Destroying client's context"
context.destroy()
print "Finishing server's process"
server.send_signal(SIGINT)
sleep(time_to_sleep)
server.send_signal(SIGKILL)
server.wait()
#!/usr/bin/env python
# coding: utf-8
from sys import stdout
from time import sleep
import zmq
def say(text):
stdout.write(text)
stdout.write('\n')
stdout.flush()
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://*:5555')
say('[server] Started - running main loop')
try:
while True:
message = socket.recv_json()
say('[server] Received JSON: {}'.format(message))
socket.send_json({'answer': 'hello'})
except KeyboardInterrupt:
context.destroy()
#!/bin/bash
export WORKON_HOME="$HOME/.virtualenvs"
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv --no-site-packages pyzmq-test
cdvirtualenv
pip install cython
git clone https://github.com/minrk/pyzmq.git
cd pyzmq/
git checkout i211
python setup.py configure --zmq=/usr/lib/
python setup.py build_ext --inplace
python setupegg.py develop
cd ..
git clone git://gist.github.com/2862393.git zeromq-bug
cd zeromq-bug
echo '*** Running client without class'
python client_without_class.py
echo '*** Running client with class'
python client.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment