package com.jackson.common.control;
import com.jackson.common.source.CommonSource;
import com.jackson.db.po.Proxy;
import com.jackson.db.po.Url;
import com.jackson.db.service.IDaoService;
import com.jackson.db.service.ProxyService;
import com.jackson.task.ITask;
import com.jackson.reservoir.ProxyPool;
import com.jackson.task.CreateTaskThread;
import com.jackson.task.proxy.ProxyValidateOkTask;
import com.jackson.task.proxy.ProxyValidateTask;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
/**
* Created by Jackson on 2016/11/16.
* 用来控制验证proxy是否可用的管理类
*/
public class ProxyController {
private final CommonSource source;
private final CreateProxyTestTaskThread createProxyTestTaskThread;
private final ScheduledThreadPoolExecutor threadPool;
private final ProxyPool proxyPool;
private final ProxyService proxyService;
private final ProxyService proxyOkService;
private boolean isOkServiceEnd = false;
private Url url ;
private ProxyController(ProxyService proxyService,Url testUrl) {
this.proxyService = proxyService;
this.url = testUrl;
proxyOkService = new ProxyService(proxyService.getTableName() + "_ok", ProxyService.TakeMethod.MAX_SPEED);
source = CommonSource.newInstance();
proxyPool = new ProxyPool();
threadPool = source.getThreadPool();
createProxyTestTaskThread = new CreateProxyTestTaskThread(proxyOkService, threadPool);
proxyOkService.setDatabaseToQueueHandler(new ProxyService.DatabaseToQueueHandler() {
@Override
public void handle(List<Proxy> list, LinkedBlockingQueue queue) {
if (list.size() == 0 &&queue.size()==0) {
if (!createProxyTestTaskThread.isAlive()) {
createProxyTestTaskThread.start();
}
isOkServiceEnd = true;
createProxyTestTaskThread.setService(ProxyController.this.proxyService);
}
}
});
}
public static ProxyController newInstance(ProxyService proxyService,Url testUrl){
return new ProxyController(proxyService,testUrl);
}
private ControlConfig controlConfig;
private void initConfig() {
if(controlConfig ==null){
controlConfig = getDefaultConfig();
}
proxyService.setProxySize(controlConfig.getGetServiceCatchSize())
.setMinProxyCatch(controlConfig.getMinServiceCatch());
proxyOkService.setProxySize(controlConfig.getGetServiceCatchSize())
.setMinProxyCatch(controlConfig.getMinServiceCatch());
createProxyTestTaskThread.setMinTaskCache(controlConfig.getMinTaskCache())
.setMaxTaskCache(controlConfig.getMaxTaskCache());
threadPool.setCorePoolSize(controlConfig.getCorePoolSize());
}
private void setControlConfig(ControlConfig controlConfig){
this.controlConfig = controlConfig;
}
/**
* 在调用start()方法之前设置,否则无效
* @param threadSize
* @return
*/
public ProxyController setThreadSize(int threadSize){
ControlConfig controlConfig = ControlConfig.builder()
.setCorePoolSize(threadSize)
.setMaxTaskCache(2*threadSize)
.setMinTaskCache(threadSize+1)
.setGetServiceCatchSize(5*threadSize)
.setMinServiceCatch(threadSize+1)
.build();
setControlConfig(controlConfig);
return this;
}
private ControlConfig getDefaultConfig(){
return ControlConfig.builder()
.setCorePoolSize(10)
.setMaxTaskCache(80)
.setMinTaskCache(20)
.setGetServiceCatchSize(100)
.setMinServiceCatch(20)
.build();
}
/**
* 添加代理到数据库,非及时插入
* @param proxy
*/
public void insert(List<Proxy> proxy) {
proxyService.insert(proxy);
}
public void start(){
initConfig();
createProxyTestTaskThread.start();
}
public ProxyService getProxyOkService() {
return proxyOkService;
}
/**
* 用来创建 从没连接成功的ip 的验证任务
*/
private class CreateProxyTestTaskThread extends CreateTaskThread<Proxy>{
public CreateProxyTestTaskThread(IDaoService<Proxy> service, ScheduledThreadPoolExecutor threadPool) {
super(service, threadPool);
}
@Override
protected Runnable getTask(Proxy obj) {
return getProxyTestTask(obj);
}
@Override
protected long getDelay(Proxy proxy) {
return 0;
}
}
private ITask getProxyTestTask(Proxy proxy){
if(isOkServiceEnd){
return new ProxyValidateTask(ProxyController.this,url,proxy);
}else {
return new ProxyValidateOkTask(ProxyController.this,url,proxy);
}
}
public ProxyService getProxyService() {
return proxyService;
}
/**
* @return 存放可用proxy的池子
*/
public ProxyPool getProxyPool() {
return proxyPool;
}
public CommonSource getCommonSource() {
return source;
}
}