Skip to content

Instantly share code, notes, and snippets.

@sauceaaron
Last active November 17, 2018 00:24
Show Gist options
  • Save sauceaaron/ebeb3a3ea6c590f711429517d15ee79e to your computer and use it in GitHub Desktop.
Save sauceaaron/ebeb3a3ea6c590f711429517d15ee79e to your computer and use it in GitHub Desktop.
Selenium DriverFactory with Queue to control session concurrency
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
public class DriverFactory
{
URL url;
SessionQueue queue;
//...
public RemoteWebDriver getSession(DesiredCapabilities capabilities)
{
if (queue.sessionsAvailable())
{
RemoteWebDriver driver = new RemoteWebDriver(url, capabilities);
queue.addSession(driver.getSessionId());
queue.update();
}
}
public void returnSession(RemoteWebDriver driver)
{
queue.removeSession(driver.getSessionId());
driver.quit();
queue.update();
}
public RemoteWebDriver waitForSessionAvaible(DesiredCapabilities capabilities) throws Exception
{
if (queue.sessionsAvailable())
{
return getSession(capabilities);
}
ReservedSessionId reservedSessionId = queue.reserveSession();
int waitTime = 0;
int interval = 10000; // 10 seconds
int maxSessionWaitTime = interval * 60; // 10 minutes
while (waitTime < maxSessionWaitTime)
{
Thread.sleep(interval);
waitTime += interval;
queue.update();
if (queue.reservedSessionAvailable(reservedSessionId))
{
RemoteWebDriver driver = new RemoteWebDriver(url, capabilities);
queue.useReservedSession(reservedSessionId, driver.getSessionId());
queue.update();
return driver;
}
}
throw new Exception("Timed out waiting for reserved session");
}
}
import org.openqa.selenium.remote.SessionId;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class SessionQueue
{
Set<SessionId> activeSessions;
LinkedList<ReservedSessionId> reservedSessions;
int queueSize = 100;
public SessionQueue(int queueSize)
{
this.queueSize = queueSize;
activeSessions = new HashSet<>();
reservedSessions = new LinkedList<>();
}
public boolean sessionsAvailable()
{
return activeSessions.size() + reservedSessions.size() < queueSize;
}
public void addSession(SessionId sessionId)
{
// add a session to redis
}
public void update()
{
//TODO: sync with redis
//check for session availability and allocate for reserved sessions
while (sessionsAvailable())
{
// TODO: convert reserved session to active session
}
}
public void removeSession(SessionId sessionId)
{
//TODO: remove session from redis
}
public ReservedSessionId reserveSession()
{
ReservedSessionId reservedSessionId = ReservedSessionId.generate();
reservedSessions.push(reservedSessionId);
// TODO: set notification of reserve session
return reservedSessionId;
}
public boolean reservedSessionAvailable(ReservedSessionId reserveSessionId)
{
return activeSessions.contains(reserveSessionId);
}
public SessionId useReservedSession(ReservedSessionId reservedSessionId, SessionId sessionId)
{
activeSessions.add(sessionId);
reservedSessions.remove(reservedSessionId);
return sessionId;
}
}
@sauceaaron
Copy link
Author

SessionQueue could be implemented using Redis, MySQL, or some message queue with pub/sub so that multiple clients can coordinate and share sessions as long as the use the DriverFactory to check them out and return them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment