背景:
目标是把gitlab发送的申请合并。
https://segmentfault.com/a/11…
上次说写合并事件的时候。应用了线程睡眠,不仅会占用tcp连贯的工夫,也会容易出很多问题。
同时发现了一些问题,起初就扭转了写法。
原来的写法:
流程:
合并issue close 和 comment事件的时候,起初又发现一个问题:
判断是否同一个issue的办法有谬误
之前是通过判断iid是否相等, 申请是否来自同一个申请
之后发现,issue的iid都是从1 开始的,所以A我的项目issue 的 iid, 可能与B我的项目issue 的 iid雷同
所以咱们须要辨别各个申请来自的我的项目
所以应用了ConcurrentHashMap,key为token,value为该我的项目待处理的GitlabRequest申请
/**
* key: access_token, github钉钉机器人的token
* value 该我的项目待处理的GitlabRequest申请
*/
private final Map<String, Queue<GitlabRequest>> map = new ConcurrentHashMap<>();
问题2: 线程睡眠
上次。应用了线程睡眠,不仅会占用tcp连贯的工夫,也会容易出很多问题。
改为了应用@Schedule
// 距离5s解决我的项目申请
@Scheduled(fixedRate = 5000)
private void sendRequest() {
// 对每个我的项目的申请队列进行解决
this.map.forEach((key, value) -> {
try {
this.handleQueue(value);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
问题3: 事件不能合并
两个能够合并的事件申请一和申请二,如果刚好卡在定时工作发送工夫的前后,会导致不能合并。
这个时候就须要在申请承受的时候判断工夫, 如果承受的时候小于两秒就不解决。
/**
* 是否持续解决
* 当最初一次申请在以后工夫 2s 内时, 不进行解决
*
* @return true 不解决 false 解决
*/
private Boolean IsNotHandle(Timestamp receivedTime) {
return System.currentTimeMillis() < receivedTime.getTime() + NOT_HANDLE_TIME;
}
解决申请队列:
public void handleQueue(Queue<GitlabRequest> queue) throws IOException {
int size = queue.size();
// 如果队列没数据,示意这段时间没有申请,间接返回
if (size == 0) {
return;
}
Iterator<GitlabRequest> iterator = queue.iterator();
while (iterator.hasNext()) {
// 获取头部元素
GitlabRequest gitlabRequest = iterator.next();
// 是否持续进行解决
if (IsNotHandle(gitlabRequest.getReceivedTime())) {
logger.info("最初一次申请在以后工夫在2s内,不进行解决");
break;
}
// 出栈
iterator.remove();
String resultJson;
// 获取解决合并事件后的json
resultJson = this.combineEventService.handleEvent(iterator, gitlabRequest);
if (resultJson == null) {
logger.info("事件合并,不发送该事件");
return;
}
this.gitLabNotifyService.handleEventData(resultJson, gitlabRequest.getEventName(), gitlabRequest.getSecret());
}
}
最初的逻辑:
发表回复