Meta -
OS: Windows
Selenium Version: 2.53
Expected Behavior -
When a client has disconnected for any reason, an attempt is always made to cleanup the session on the remote node, at least by the expiration of the idle timeout.
Actual Behavior -
If the Selenium Grid hub detects a client "is gone" or "Socket timed out", it terminates/frees the session on the Grid, but no attempt is made to delete the session on the remote node. This is handled in RequestHandler.java:#L131-136:
} catch (ClientGoneException e) {
log.log(Level.WARNING, "The client is gone for session " + session + ", terminating");
registry.terminate(session, SessionTerminationReason.CLIENT_GONE);
} catch (SocketTimeoutException e) {
log.log(Level.SEVERE, "Socket timed out for session " + session + ", " + e.getMessage());
registry.terminate(session, SessionTerminationReason.SO_TIMEOUT);
registry.terminate() specifies this in the docstring:
/**
* Ends this test session for the hub, releasing the resources in the hub / registry. It does not
* release anything on the remote.
This means sessions are left on the node and will never be cleaned up, which can cause dozens of web browsers left running eventually leading to resource exhaustion on the node and slow/failing tests. maxSession does not matter in this case.
We see this in our environment when our continuous integration server (TeamCity) kills a build on a Windows agent during a Selenium test, either manually or due to overrunning the allowed run time.
Steps to reproduce -
I can only reproduce this using Windows as a client, I am not sure if there's something different in the way it handles connections, or why exactly. I imagine it's possible on other OS, but not as easy to reproduce.
Since this is a Grid hub specific issue, there are a few steps:
-
Start a grid server with an idle timeout of 10 seconds:
java -jar selenium-server-standalone-2.53.0.jar -role hub -timeout 10
-
Start a Grid node on the same machine:
java -jar selenium-server-standalone-2.53.0.jar -role node
-
On a Windows machine from command prompt run a script equivalent to this (replace localhost with the Grid IP, if different):
# Start a Grid session and browse to google.com 30 times
from selenium import webdriver
driver = webdriver.Remote('http://localhost:4444/wd/hub', {'browserName':'chrome'})
for i in range(30):
driver.get('http://www.google.com')
-
While the script is running close the terminal window (do not ctrl-c or kill the process)
You should see this in the log:
13:35:12.062 WARN - The client is gone for session ext. key 59d33b92-47ac-4b44-a5a1-b53e32b4455e
This means the session is freed on the Grid, but the session is left running on the node. You can confirm this by browsing to your node's URL (e.g. http://localhost:5555/wd/hub/static/resource/hub.html).
Solutions -
I have a (very small) commit on my forked branch which removes the session.terminate() calls when handling these types of client disconnects - jessehudl@fe5fafb
Removing the session.terminate() allows the Grid to clean up the sessions like it usually would - after the idle timeout has expired. If you re-run the "Steps to reproduce", you will see that after the client is gone, the session is still cleaned up after 10 seconds and the browser is closed on the node.
This is working well for us internally but I wanted to gain some insight from the core devs before submitting a PR:
- Is there a reason these sessions are currently handled the way they are?
- Is there a better way to clean them up?
- Since 2.X development is closed, would this have to be submitted to 3.X?
Meta -
OS: Windows
Selenium Version: 2.53
Expected Behavior -
When a client has disconnected for any reason, an attempt is always made to cleanup the session on the remote node, at least by the expiration of the idle timeout.
Actual Behavior -
If the Selenium Grid hub detects a client "is gone" or "Socket timed out", it terminates/frees the session on the Grid, but no attempt is made to delete the session on the remote node. This is handled in RequestHandler.java:#L131-136:
registry.terminate()specifies this in the docstring:This means sessions are left on the node and will never be cleaned up, which can cause dozens of web browsers left running eventually leading to resource exhaustion on the node and slow/failing tests.
maxSessiondoes not matter in this case.We see this in our environment when our continuous integration server (TeamCity) kills a build on a Windows agent during a Selenium test, either manually or due to overrunning the allowed run time.
Steps to reproduce -
I can only reproduce this using Windows as a client, I am not sure if there's something different in the way it handles connections, or why exactly. I imagine it's possible on other OS, but not as easy to reproduce.
Since this is a Grid hub specific issue, there are a few steps:
Start a grid server with an idle timeout of 10 seconds:
Start a Grid node on the same machine:
On a Windows machine from command prompt run a script equivalent to this (replace localhost with the Grid IP, if different):
While the script is running close the terminal window (do not ctrl-c or kill the process)
You should see this in the log:
This means the session is freed on the Grid, but the session is left running on the node. You can confirm this by browsing to your node's URL (e.g. http://localhost:5555/wd/hub/static/resource/hub.html).
Solutions -
I have a (very small) commit on my forked branch which removes the
session.terminate()calls when handling these types of client disconnects - jessehudl@fe5fafbRemoving the
session.terminate()allows the Grid to clean up the sessions like it usually would - after the idle timeout has expired. If you re-run the "Steps to reproduce", you will see that after the client is gone, the session is still cleaned up after 10 seconds and the browser is closed on the node.This is working well for us internally but I wanted to gain some insight from the core devs before submitting a PR: