I'm doing a python script that writes some data to a mongodb.
I need to close the connection and free some resources, when finishing.
How is that done in Python?
Use close() method on your MongoClient instance:
client = pymongo.MongoClient()
# some code here
client.close()
Cleanup client resources and disconnect from MongoDB.
End all server sessions created by this client by sending one or more endSessions commands.
Close all sockets in the connection pools and stop the monitor threads.
The safest way to close a pymongo connection would be to use it with 'with':
with pymongo.MongoClient(db_config['HOST']) as client:
db = client[ db_config['NAME']]
item = db["document"].find_one({'id':1})
print(item)
Adding to #alexce's answer, it's not always true. If your connection is encrypted, MongoClient won't reconnect:
def close(self):
...
if self._encrypter:
# TODO: PYTHON-1921 Encrypted MongoClients cannot be re-opened.
self._encrypter.close()
also, since version 4.0, after calling close() client won't reconnect in any case.
def close(self) -> None:
"""Cleanup client resources and disconnect from MongoDB.
End all server sessions created by this client by sending one or more
endSessions commands.
Close all sockets in the connection pools and stop the monitor threads.
.. versionchanged:: 4.0
Once closed, the client cannot be used again and any attempt will
raise :exc:`~pymongo.errors.InvalidOperation`.
Related
I'm writing a pair of client/server scripts where it is important to maintain connection as well as detect quickly when the client disconnects. The server normally only sends data, so to test if the client has disconnected normally, I set the socket to timeout mode and check what it returns:
try: # check if client disconnect
c.settimeout(1)
if not (c.recv(1024)):
print("## Socket disconnected! ##")
c.settimeout(None)
closeConnection(c)
return
except Exception as e:
print(e)
c.settimeout(None)
This works instantly if I close the client. However, if I disconnect the WiFi on the client machine, the recv on the server doesn't return anything. It just times out like it would if the connection was up but there wasn't anything being sent.
I've tried using send() to send empty messages to the client as a way to poll. When I do this, the operation succeeds and returns 0 regardless of if the client has disconnected.
I have a very simple Python (Flask socket.io) application which works as a server and another app written in AngularJS which is a client.
In order to handle connected and disconnected client I use respectlivy:
#socketio.on('connect')
def on_connect():
print("Client connected")
#socketio.on('disconnect')
def on_disconnect():
print("Client disconnected")
When Client connects to my app I get information about it, in case if client disconnect (for example because of problems with a network) I don't get any information.
What is the proper way to handle the situation in which client disconnects unexpectedly?
There are two types of connections: using long-pooling or WebSocket.
When you use WebSocket clients knows instantly that server was disconnected.
In the case of long-polling, there is need to set ping_interval and pint_timeout parameters (I also find information about heartbeat_interval and heartbeat_timeout but I don't know how they are related to ping_*).
From the server perspective: it doesn't know that client was disconnected and the only way to get that information is to set ping_interval and ping_timeout.
I am implementing a tornado socket server based on this code:
https://gist.github.com/robcowie/974695
Client is Python simple socket client. When I call socket.close() in client, nothing happens in server. I put full print traces in the server and closing is not detected nowhere.
I know I can detect the closure for example sending a string "CNNDEND" which means closing. But I wonder if there is any way to detect on server socket.close() from client.
in Connection __init__:
self.stream.set_close_callback(self.__onClose)
in Connection class:
def __onClose(self):
print 'close detected'
I have program which has servers interacting with each other using Twisted's remote procedure calls, and I run in problems with closing connections when they are not needed anymore. Connections should be able to close itself in both sides.
Case 1: How do I close connection in connecting part?
factory = pb.PBClientFactory()
reactor.connectTCP(ip, port, factory)
deferred = factory.login(credentials.UsernamePassword(username, password), client=self)
deferred.addCallbacks(self.connectedToServer, self.errorConnectingToServer)
def connectedToServer(self, server):
self.server = server
# Closing connection comes here
Case 2: How do I close connection in server part?
class MyPerspective(pb.Avatar):
def connected(self, server):
self.client = server
# Closing connection comes here
At the moment I use raising pb.Error() to close connection, but I don't think that's the proper way to do it.
Another option is reference.broker.transport.loseConnection().
RemoteReference instances which are created over a PB connection are given a broker attribute. The broker attribute refers to the protocol instance that created them. As usual for a protocol, the broker has a transport attribute, and the transport has a loseConnection method.
I'm using python2.6 with HTTPServer and the ThreadingMixIn, which will handle each request in a separate thread. I'm also using HTTP1.1 persistent connections ('Connection: keep-alive'), so neither the server or client will close a connection after a request.
Here's roughly what the request handler looks like
request, client_address = sock.accept()
rfile = request.makefile('rb', rbufsize)
wfile = request.makefile('wb', wbufsize)
global server_stopping
while not server_stopping:
request_line = rfile.readline() # 'GET / HTTP/1.1'
# etc - parse the full request, write to wfile with server response, etc
wfile.close()
rfile.close()
request.close()
The problem is that if I stop the server, there will still be a few threads waiting on rfile.readline().
I would put a select([rfile, closefile], [], []) above the readline() and write to closefile when I want to shutdown the server, but I don't think it would work on windows because select only works with sockets.
My other idea is to keep track of all the running requests and rfile.close() but I get Broken pipe errors.
Ideas?
You're almost there—the correct approach is to call rfile.close() and to catch the broken pipe errors and exit your loop when that happens.
If you set daemon_threads to true in your HTTPServer subclass, the activity of the threads will not prevent the server from exiting.
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
daemon_threads = True
You could work around the Windows problem by making closefile a socket, too -- after all, since it's presumably something that's opened by your main thread, it's up to you to decide whether to open it as a socket or a file;-).