All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aggrepoint.utils.http.HttpThrottling Maven / Gradle / Ivy

The newest version!
package com.aggrepoint.utils.http;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 
 * 实现Http请求速度控制
 * 
 * 使用一组HttpChannel尽快发送Http请求,每个channel上的请求之间保持一定时间间隔
 * 
 * 每个HttpThrottling内建立一个用于延时执行任务的线程
 * 
* * @author jiangmingyang */ public class HttpThrottling implements HttpRequester { /** 等待运行的请求队列 */ private ArrayBlockingQueue waitingQueue; private static class Waiting { HttpTask task; ResponseFuture future; public Waiting(HttpTask task) { this.task = task; } } public HttpThrottling(HttpChannel[] channels, int requestInterval, int maxWaiting) { long[] lastRequestTime = new long[channels.length]; waitingQueue = new ArrayBlockingQueue<>(maxWaiting); // 请求线程 new Thread(() -> { while (true) { Waiting waiting = null; try { waiting = waitingQueue.poll(60, TimeUnit.SECONDS); } catch (InterruptedException e) { } if (waiting == null) { continue; } boolean run = false; do { long waitTime = requestInterval; // 寻找可用的channel for (int i = 0; i < channels.length; i++) { if (requestInterval > 0) { long w = requestInterval - (System.currentTimeMillis() - lastRequestTime[i]); if (w > 0) { if (w < waitTime) waitTime = w; continue; } } // 找到可用的channel lastRequestTime[i] = System.currentTimeMillis(); waiting.future.setResponseFuture(channels[i].request(waiting.task).getListenableFuture()); run = true; break; } if (!run) { // 没有可用channel, 等待 try { TimeUnit.MICROSECONDS.sleep(waitTime); } catch (InterruptedException e) { } } } while (!run); } }, HttpThrottling.class.getName()).start(); } /** * 增加一个任务 * * @param task * @return 返回NULL说明等待的请求已经超过限量 * @throws InterruptedException */ @Override public ResponseFuture request(HttpTask task) { if (waitingQueue.remainingCapacity() == 0) { if (task.getExecutor() == null) task.getProcess().accept(null, new ThrottlingOverflowException()); else task.getExecutor().execute(() -> { task.getProcess().accept(null, new ThrottlingOverflowException()); }); return null; } Waiting waiting = new Waiting(task); waiting.future = new ResponseFuture(() -> waitingQueue.remove(waiting)); try { waitingQueue.put(waiting); } catch (InterruptedException e) { if (task.getExecutor() == null) task.getProcess().accept(null, e); else task.getExecutor().execute(() -> { task.getProcess().accept(null, e); }); return null; } return waiting.future; } /** * 从队列中撤销还未执行到的请求 * * @param waiting * @return */ public boolean cancel(Waiting waiting) { return waitingQueue.remove(waiting); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy