Search code examples
socketsmultiprocessingtornadopython-3.6pickle

How to send web socket connection to different process in tornado?


I am using tornado to implement the server with web sockets. I have some multi core CPU and I want to use the other CPU as well. So I though of using python multiprocess module. I want to accept the connection on the main process and send the data using other process. My questions are:

  1. Is it possible to share the socket information between processes?
  2. Is it better to use pickling or is there any other method that I can use?
  3. If I use pickling the additional duplicates file descriptors that are created by it will affect the number of file descriptors the OS can handle or is it the same file descriptor shared between the processes?

Explanation: There will be a lot of incoming connections and there will be a lot of messages from the client side so I do not want to the main event to loop to be stuck in sending the data. That is why I am trying to use different process to send the data to the connections.

Output of strace I have started strace and given the process id from which I am sending data to web sockets. The output of strace looks like this:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 91.01    0.019570           0    441736           sendto
  3.60    0.000774           0     29314           read
  3.14    0.000675           0     30623           clock_gettime
  1.15    0.000248           0      2909           write
  0.96    0.000206           0     11855           epoll_wait
  0.13    0.000029           0      1534       680 recvfrom
  0.00    0.000000           0        17           open
  0.00    0.000000           0        34           close
  0.00    0.000000           0        17           stat
  0.00    0.000000           0        17           fstat
  0.00    0.000000           0        34           poll
  0.00    0.000000           0        39           mmap
  0.00    0.000000           0        26           munmap
  0.00    0.000000           0       408           brk
  0.00    0.000000           0       134           ioctl
  0.00    0.000000           0        34           socket
  0.00    0.000000           0        34        17 connect
  0.00    0.000000           0       300           setsockopt
  0.00    0.000000           0        17           getsockopt
  0.00    0.000000           0       200           fcntl
  0.00    0.000000           0        17           gettimeofday
  0.00    0.000000           0      1185           epoll_ctl
  0.00    0.000000           0       178        78 accept4
------ ----------- ----------- --------- --------- ----------------
100.00    0.021502                520662       775 total

Is there any reason that i am getting error recvfrom and connect?


Solution

  • No, Tornado does not support this. There are techniques like SCM_RIGHTS to transfer file descriptors to other processes, but this will give you a raw socket in the other process, not a Tornado websocket object (and there is no supported way to construct a websocket object for this socket).

    The recommended approach with Tornado is to run one process per CPU and let them share traffic by either putting them behind a load balancer or using SO_REUSEPORT. Sending the data in Tornado is non-blocking; you must make sure that your own code is non-blocking too (using asynchronous interfaces or thread pools).