jeffbass / imagezmq

A set of Python classes that transport OpenCV images from one computer to another using PyZMQ messaging.
MIT License
1.01k stars 160 forks source link

Add send and receive timeout options on ImageSender #2

Closed youngsoul closed 5 years ago

youngsoul commented 5 years ago

While working through the PyImageSearch tutorial, I noticed that if I stopped the server and restarted the client would not connect. If I added send and receive timeouts on the socket, then it gave me a chance to re-establish the connection the client and server would automatically begin to send images again.

If there is a better way to handle that - I am open to suggestions.

Thanks for this great library and I am glad Adrian posted a blog on it!

jeffbass commented 5 years ago

Thanks for your contribution. When you stop the server and restart the client (before restarting the server), it is common for ZMQ to hang when using the simple REQ/REP protocol. This is actually a design choice made by the ZMQ team for the simplest REQ / REP pattern (which is the one imagezmq currently uses). Quoting from the ZMQ docs:

If you kill the server (Ctrl-C) and restart it, the client won't recover properly. Recovering from crashing processes isn't quite that easy. Making a reliable request-reply flow is complex enough that we won't cover it until Chapter 4 - Reliable Request-Reply Patterns.

In the ZMQ "simplest" REQ / REP pattern, clients can restart all they want to and things keep running. But, if the server restarts, clients need to restart. The server must always be started first. If the server restarts, the clients need to be restarted.

I suspect that your sent_timeout and recv_timeout worked because you allowed enough time to restart the server. Let me take a look at your code for few days and I'll get back to you.

Thanks!

youngsoul commented 5 years ago

Thank you for your feedback. I am "picking up what you are putting down" as they say.

Here is a GitHub link to where I am using my suggested changes.

https://github.com/youngsoul/pyimagesearch-video-streaming

In the client I use the timeout exception from the socket, to wait a little longer and then create a new ImageSender instance.

So far it has been pretty resilient to server restarts.

I absolutely understand if this change is not something you want to incorporate.

Again - thanks for your library. It is pretty darn cool and I am having fun playing with it.

jeffbass commented 5 years ago

Thanks again for your contribution. I like what you have done in your context manager and creating a new ImageSender instance after a timeout. However, my use case is (see my imagenode and imagehub repositories) actually causes the client program to restart when there is a communication interruption or timeout. With 10-12 clients per server, I've found that having the clients restart quickly without a timeout works well for me. I'm not going to merge your contribution, but appreciate what you've done and will be watching your fork with interest. Thanks again!

jeffbass commented 5 years ago

Closed #2