Reusing the same connection used within a session with a loop - python

I just want to inquire regarding reusing the same connection while having a loop sending the same POST request. Assume I have this code:
import requests
import time
r = requests.Session()
url = "http://somenumbers.php"
while True:
x = r.post(url)
time.sleep(10)
Now according to the documentation of requests library
Excellent news — thanks to urllib3, keep-alive is 100% automatic within a session! Any requests that you make within a session will automatically reuse the appropriate connection!
Note that connections are only released back to the pool for reuse once all body data has been read; be sure to either set stream to False or read the content property of the Response object
Does this work for the code up above? I am trying to prevent sending the same request in case the server freezes or a read timeout occurs. In Issue with sending POST requests using the library requests I go over the whole problem, and one of the suggestions is to reuse the connection, but
Isn't sending the same request on the same connection will just mean multiple entries, or is it going to fix the issue since it will only pull back when one entry is sent as the documentation states?
Assuming the latter is true, won't that affect performance and cause long delays since the request is trapped inside the connection?!

r.post is a blocking call. The function will only return once the request has been sent and a response is received. As long as you access x.content before the loop terminates, the next loop will re-use the underlying TCP connection.
Isn't sending the same request on the same connection will just mean
multiple entries, or is it going to fix the issue since it will only
pull back when one entry is sent as the documentation states?
requests doesn't cache the response. It will not check if a previous request having the same parameters was made. If you need that, you will have to build something on your own.
won't that affect performance and cause long delays since the request
is trapped inside the connection
requests will only re-use an available connection. If no free connection exists, a new connection will be established. You can use requests.packages.urllib3.poolmanager.PoolManager to control the number of connections in the pool.

Related

Pending requests with Python's SimpleHTTPServer

I'm making an anonymous chat application, similar to Omegle. My method of approach instead of using sockets is to use a REST API, but to add a bit of a twist. When a user makes a request, such as POST /search (find a match), the request is held by the server until another user sends a POST /search. Once two people have done this, both requests are responded to which lets the client know to switch to a chat page. This is also done with a pending GET /events request, which is only responded to by the server if there's any new events to be sent.
This works very well in theory with the flow of this application; however, since I'm using SimpleHTTPServer - which is a very basic library - requests are not handling asynchronously. This means that if I block one request until information requirements are fulfilled, no other requests can be accepted. For this kind of project I really don't want to take the time to learn an entirely new library/sub-language for asynchronous requests handling, so I'm trying to figure out how I can do this.
def waitForMatch(client):
# if no other clients available to match:
if not pendingQueue:
# client added to pending queue
pendingQueue.append(client)
client["pending"] = True
while client["pending"]:
time.sleep(1)
# break out and let the other client's waitForMatch call create the chatsession
return
# now there's a client available to match
otherClient = pendingQueue.pop()
otherClient["pending"] = False
# chat session created
createChatSession(otherClient, client)
This is the code I currently have, which won't work with non-async requests.

Close MySQL Connection Without Waiting for Response in Flask

I'm using MySQL through SQLAlchemy in a Flask App. In situations where I need to use a db connection, I can see that closing that connection at the end of a request means that I have to wait for a ROLLBACK to be run on the connection against my database, which means waiting for an extra request to travel to the database and back. In my geographical situation, waiting for the extra time for this to happen can take >100ms. This seems like a very avoidable cost as there is really no reason to make a user submitting a request to wait for this final back-and-forth with the database.
Is there any reason not to close the connection asynchronously, or somehow after the response has been sent back to the user? Is there an accepted way of doing this?

Why does telegram.Bot.getUpdates() long polling returns immediately?

According to telegram api, the getUpdates function receives incoming updates using long polling (wiki).
From wiki:
If the server does not have any information available for the client
when the poll is received, instead of sending an empty response, the
server holds the request open and waits for response information to
become available. Once it does have new information, the server
immediately sends an HTTP/S response to the client, completing the
open HTTP/S Request.
Then, why does the function getUpdates() returns immediately, even though the timeout parameter is set?
The function call:
bot.getUpdates(offset=lastUpdateID, timeout=120)
There are no new updates and the offset=lastUpdateID is the last update.
I'm using library python telegram bot library
The problem was I asked for offset=lastUpdateID x, and I should have asked for offset=lastUpdateID x + 1

What are good ways to create a HTTP session with simultaneous requests?

I have a problem and can't solve it. Maybe I'm making it too hard or complex or I'm just going in the wrong direction and thinking of things that don't make sense. Below is a description of what happens. (Multiple tabs opened in a browser or a page that requests some other pages at the same time for example.)
I have a situation where 3 requests are received by the web application simultaneously and new user session has to be created. This session is used to store notification, XSRF token and login information when the user logs in. The application uses threads to handle requests (CherryPy under Bottle.py).
The 3 threads (or processes in case or multiple application instances) start handling the 3 requests. They check the cookie, no session exists, and create a new unique token that is stored in a cookie and in Redis. This will all happen at the same time and they don't know if a session already has been created by another thread, because all 3 tokens are unique.
These unused sessions will expire eventually, but it's not neat. It means everytime a client simultaneously does N requests and a new session needs to be created, N-1 session are useless.
If there is a property that can be used to identify a client, like an IP address, it would be a lot easier, but an IP address is not safe to use in this case. This property can be used to atomically store a session in Redis and other requests would just pick up that session.
If this is through a browser and is using cookies then this shouldn't be an issue at all. The cookie will, from what I can tell, the last session value that it is set to. If the client you are using does not use cookies then of course it will open a new session for each connection.

Python Webserver: How to serve requests asynchronously

I need to create a python middleware that will do the following:
a) Accept http get/post requests from multiple clients.
b) Modify and Dispatch these requests to a backend remote application (via socket communication). I do not have any control over this remote application.
c) Receive processed results from backend application and return these results back to the requesting clients.
Now the clients are expecting a synchronous request/response scenario. But the backend application is not returning the results synchronously. That is, some requests take much longer to process than others. Hence,
Client 1 : send http request C1 --> get response R1
Client 2 : send http request C2 --> get response R2
Client 3 : send http request C3 --> get response R3
Python middleware receives them in some order: C2, C3, C1. Dispatches them in this order to backend (as non-http messages). Backend responds with results in mixed order R1, R3, R2. Python middleware should package these responses back into http response objects and send the response back to the relevant client.
Is there any sample code to program this sort of behavior. There seem to be something like 20 different web frameworks for python and I'm confused as to which one would be best for this scenario (would prefer something as lightweight as possible ... I would consider Django too heavy ... I tried bottle, but I am not sure how to go about programming that for this scenario).
================================================
Update (based on discussions below): Requests have a request id. Responses have a response id (which should match the request id that they correspond to). There is only one socket connection between the middleware and the remote backend application. While we can maintain a {request_id : ip_address} dictionary, the issue is how to construct a HTTP response object to the correct client. I assume, threading might solve this problem where each thread maintains its own response object.
Screw frameworks. This exactly the kind of task for asyncore. This module allows event-based network programming: given a set of sockets, it calls back given handlers when data is ready on any of them. That way, threads are not necessary just to dumbly wait for data on one socket to arrive and painfully pass it to another thread. You would have to implement the http handling yourself, but examples can be found on that. Alternatively, you could use the async feature of uwsgi, which would allow your application to be integrated with an existing webserver, but that does not integrate with asyncore by default --- though it wouldn't be hard to make it work. Depends on specific needs.
Quoting your comment:
The middleware uses a single persistent socket connection to the backend. All requests from middleware are forwarded via this single socket. Clients do send a request id along with their requests. Response id should match the request id. So the question remains: How does the middleware (web server) keep track of which request id belonged to which client? I mean, is there any way for a cgi script in middleware to create a db of tuples like and once a response id matches, then send a http response to clientip:clienttcpport ?
Is there any special reason for doing all this processing in a middleware? You should be able to do all this in a decorator, or somewhere else, if more appropriate.
Anyway, you need to maintain a global concurrent dictionary (extend dict and protect it using threading.Lock). Upon a new request, store the given request-id as key, and associate it to the respective client (sender). Whenever your backend responds, retrieve the client from this dictionary, and remove the entry so it doesn't accumulate forever.
UPDATE: someone already extended the dictionary for you - check this answer.
Ultimately your going from the synchronous http request-response protocol from your clients to an asynchronous queuing/messaging protocol with your backend. So you've two choices (1) either make requests wait until the backend has no outstanding work, then process one (2) write something that marries the backend responses with their associated request (using a dictionary of request or something)
One way might be to run your server in one thread while dealing with your backend in another (see... Run Python HTTPServer in Background and Continue Script Execution) or maybe look at aiohttp (https://docs.aiohttp.org/en/v0.12.0/web.html)

Categories