pythonmultithreadingpython-2.7xml-rpcxmlrpclib

Multithreading problems with xmlrpclib.ServerProxy under python 2.7


I have an application which instantiates an xmlrpclib.ServerProxy once, and then passes it to several threads (web application requests), which all perform XML/RPC calls simultaneously. This works well with python 2.6. With python 2.7, we're getting a lot of errors (ResponseNotReady, CannotSendRequest) as soon as we're in a multi-threaded environment.

# This code works well in python 2.6, and breaks in python 2.7.

import xmlrpclib
import thread

proxy = xmlrpclib.ServerProxy("http://localhost:5000/")

def fetch_users():
  print proxy.getUsers()

for _ in range(10):
  thread.start_new_thread(fetch_users, ())

while(1):
  pass

What is the problem here, and is there a thread-safe way of re-using the ServerProxy-object?


Solution

  • We found the cause for the problem: In python 2.6, a TCP connection is created on every XML/RPC method call. Python 2.7, on the other hand, opens a single TCP connection for each ServerProxy-object, and keeps it open (with servers that support keep-alive). Furthermore, the class is not thread-safe, so that concurrent requests may interfere with each other.

    Apparently, the 2.6 version was thread-safe implicitely, as TCP connections do not get reused and all the connection-specific data seems to be kept in non-shared stack variables.

    So possible solutions would be:

    1. Create a ServerProxy object (and implicitely open a TCP connection) for each thread
    2. Lock the access to a single, shared ServerProxy object
    3. Implement a request queue