2

In my (python) code I have a thread listening for changes from a couchdb feed (continuous changes). The changes request has a timeout parameter which is too big in certain circumstances (for example when a user wants to interrupt the program manually with ^C).

  • How can I abort a long-running blocking http request?
  • Is this possible, or do I need to reduce the timeout to make my program more responsive?

This would be unfortunate, because having a timeout small enough to make the program really responsive (say, 1s), means that there are lots of connections being created (one per second!), which defeats the purpose of listening to changes, and makes it very difficult to make sure that we are not missing any changes (in the re-connecting timespan we can indeed miss changes, so that special code is needed to handle that case)

The other option is to forcefully abort the thread, but that is not really an option in python.

Community
  • 1
  • 1
blueFast
  • 41,341
  • 63
  • 198
  • 344

2 Answers2

2

If I understand correctly it looks like you are waiting too long between requests before deciding whether to respond to the users or not. You are right continuously closing and creating new connections will defeat the purpose of changes feed.

A solution could be to use heartbeat query parameter in which couchdb will keep sending newlines to tell the client that the connection is still alive.

http://localhost:5984/hello/_changes?feed=continuous&heartbeat=1000&include_docs=true

as long as you are getting heartbeats (newlines) you can be sure that you are getting new changes. A new line will indicate that no changes have occurred. Where as an actual change will be reported back. No need to close the connection. Respond to your clients if resp!="/n"

Akshat Jiwan Sharma
  • 15,430
  • 13
  • 50
  • 60
  • Yes, I have already come to this conclusion (see my comment below). The problem with this is that the `couchdb-python` library is swallowing the heartbeats, so I have made my own changes method in order to give the consumers a chance to react to external events when a heartbeat arrives. – blueFast Jul 03 '14 at 09:58
1

Blocking the thread execution in general prevents the thread from beeing terminated. You need to wait until the request timed out. But this is already clear. Using a library that supports non blocking requests is maybe a solution, but I don't know if there is any. Anyway ... you've mentioned that reducing the timeout will lead to more connections. I'd suggest to implement a waiting loop between requests that can be interrupted by an external signal to terminate the thread. with this loop you can control the number of requests independent from the timeout.

Connor
  • 36
  • 2
  • I have just realized that couchdb allows for a heartbeat parameter. I can use the heartbeat signals to evaluate an external stop event. This does not solve the general "stop blocking http request" problem that I have described, but is good enough for my case. By using the heartbeat I can use a single connection, and be responsive by putting a small heartbeat. The only drawback is that some network load is being generated by sending frequent heartbeats, but this is definitely better than having to re-create the connection each time. – blueFast Jul 03 '14 at 08:38