package com.brucezee.jspider.selenium;
import com.brucezee.jspider.selenium.common.LandlordBlockingQueue;
import com.brucezee.jspider.selenium.common.enums.DriverType;
import com.brucezee.jspider.Request;
import com.brucezee.jspider.SiteConfig;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* WebDriverę±
* Created by brucezee on 2017/1/11.
*/
public class WebDriverPool {
private static final int DEFAULT_CAPACITY = 5;
private WebDriverFactory factory;
private WebDriverChooser chooser;
private int capacity = DEFAULT_CAPACITY;
private ReentrantLock lock = new ReentrantLock();
private Map<DriverType, LandlordBlockingQueue<WebDriverEx>> queueMap = new HashMap<DriverType, LandlordBlockingQueue<WebDriverEx>>(3);
public WebDriverPool(WebDriverFactory factory) {
this(factory, DEFAULT_CAPACITY);
}
public WebDriverPool(WebDriverFactory factory, int capacity) {
this(factory, new DefaultWebDriverChooser(DriverType.CHROME), capacity);
}
public WebDriverPool(WebDriverFactory factory, WebDriverChooser chooser, int capacity) {
this.factory = factory;
this.chooser = chooser;
this.capacity = capacity;
}
public WebDriverEx getWebDriver(SiteConfig siteConfig, DriverConfig driverConfig, Request request) throws IOException, InterruptedException {
DriverType driverType = chooser.choose(request);
LandlordBlockingQueue<WebDriverEx> queue = null;
queue = queueMap.get(driverType);
if (queue == null) {
lock.lockInterruptibly();
try {
queue = queueMap.get(driverType);
if (queue == null) {
queue = new LandlordBlockingQueue<WebDriverEx>(capacity);
queueMap.put(driverType, queue);
}
} finally {
lock.unlock();
}
}
WebDriverEx poll = queue.poll();
if (poll != null) {
return poll;
}
if (queue.isNeedMore()) {
queue.add(factory.createWebDriver(siteConfig, driverConfig, driverType));
}
return queue.poll(siteConfig.getConnectionRequestTimeout(), TimeUnit.MILLISECONDS);
}
public void returnWebDriver(WebDriverEx webDriver, Request request) {
DriverType driverType = chooser.choose(request);
BlockingQueue<WebDriverEx> queue = queueMap.get(driverType);
if (queue != null) {
try {
queue.put(webDriver);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutdownWebDriver(WebDriverEx webDriver, Request request) {
DriverType driverType = chooser.choose(request);
BlockingQueue<WebDriverEx> queue = queueMap.get(driverType);
if (queue != null) {
webDriver.shutdown();
if (queue instanceof LandlordBlockingQueue) {
((LandlordBlockingQueue) queue).resetOne();
}
}
}
public void shutdown() {
synchronized (queueMap) {
for (Map.Entry<DriverType, LandlordBlockingQueue<WebDriverEx>> entry : queueMap.entrySet()) {
shutdown(entry.getValue());
}
}
}
private void shutdown(BlockingQueue<WebDriverEx> queue) {
if (queue != null) {
while (!queue.isEmpty()) {
try {
queue.take().shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public boolean isWebDriverExpired(WebDriverEx webDriver, long expireMillis) {
return expireMillis > 0 && System.currentTimeMillis() - webDriver.getCreatedTime().getTime() >= expireMillis;
}
public void shutdownOrReturn(WebDriverEx webDriver, Request request, long expireMillis) {
if (isWebDriverExpired(webDriver, expireMillis)) {
shutdownWebDriver(webDriver, request);
} else {
returnWebDriver(webDriver, request);
}
}
}