Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZMQ hanging - ZMQSocket::send

I've been testing out PHP websockets with Ratchet, and everything was working perfectly up until ZMQSocket::send suddenly started to hang for no apparent reason.

$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'notify');
$res = $socket->send(json_encode($entryData)); //Hangs here.

Note that I can use ZMQ::MODE_NOBLOCK, and that will stop the hanging, but it doesn't fix the issue. i.e. The client still isn't receiving anything. I've also rebooted my box, which doesn't fix the issue.

  • Ubuntu 12.04.1 LTS
  • PHP Version 5.3.10 - FPM/(& CLI for the push server)
  • ZMQ extension version 1.1.2
  • libzmq version 2.1.11

Update: I seemed to have fixed the issue by changing my code to:

$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'notify');
$socket->setSockOpt(ZMQ::SOCKOPT_LINGER, 30); //ADDED
$socket->connect("tcp://localhost:5557"); //ADDED
$res = $socket->send(json_encode($entryData));

Now the question is, why did it hang in the first place, when it was working fine for about an hour or two? Is there something that I need to be looking out for?

like image 662
Wayne Whitty Avatar asked Feb 14 '14 08:02

Wayne Whitty


1 Answers

First off, I'm not sure if this is a valid answer, but I've been playing with php-zmq for a few days now and I've been having a few issues myself. Your question lead me to an epiphany which will likely solve my issues, and I suspect yours might be related.

With my last php-zmq problem, I was testing the round-trip time between my laptop and my VPS using the tripping method in the zguide. All I did was change a copy of the tripping.php script on my laptop by adding the URL to my VPS, so that it would connect to the same script which was running remotely on the VPS. I was running the synchronous section in a long while loop, and the async section using the same for loop.

I noticed that only one 'client' was able to connect at a time while doing the synchronous loop, whether trying to connect multiple clients from my laptop, or one from my laptop and one from a different server, etc. Only one was able to connect at a time, period. I also noticed in the async section that my messages per second was dropping from around 100 messages per second to around 2 seconds per message as soon as messages started arriving back at my laptop. My laptop can easily do 10+ HTTP requests per second using cURL, so 2 seconds per message is not network related.

I've been a PHP extension developer and PHP core hacker for 6 years and I've ran into issues like this before. I'm pretty sure that its from a concurrency issue between PHP userspace and the internal Zeromq threads. In other words, the Zeromq IO threads are sending commands to the main Zeromq thread, but the main zeromq thread is executing within PHP via Zend engine and is bound to the same basic behaviour as other PHP methods/functions. I'm not sure yet if we can expect the exact same behaviour in php-zmq that we can in czmq or other zeromq bindings because of this - PHP is very synchronous by nature, and zeromq is asynchronous. My experience has been positive for most part when using non-blocking patterns in php-zmq.

Edit: to claifify the possible issue - Zeromq handles all IO asynchronously in separate threads. Blocking behavior (such as req/rep) is created by messaging between the IO threads and the main thread, rather than actual blocking/synchronous IO. It is the messaging and synchronizing between threads that I think might be misbehaving when within PHP. The 'non-blocking' Zeromq patterns seem to be working fine. The blocking patterns work but are displaying weird behavior in these remote cases.

like image 71
JSON Avatar answered Oct 17 '22 17:10

JSON