2

背景:

目的是把gitlab发送的请求合并。

https://segmentfault.com/a/11...
上次说写合并事件的时候。使用了线程睡眠,不仅会占用tcp连接的时间,也会容易出很多问题。

同时发现了一些问题,后来就改变了写法。

原来的写法:
image.png

流程:

image.png

合并issue close 和 comment事件的时候,后来又发现一个问题:

判断是否同一个issue的方法有错误

之前是通过判断iid是否相等, 请求是否来自同一个请求

image.png

之后发现,issue的iid都是从1 开始的,所以A项目issue 的 iid, 可能与B项目issue 的 iid相同

image.png

所以我们需要区分各个请求来自的项目

所以使用了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: 事件不能合并

image.png

两个可以合并的事件请求一和请求二,如果刚好卡在定时任务发送时间的前后,会导致不能合并。

这个时候就需要在请求接受的时候判断时间, 如果接受的时候小于两秒就不处理。

  /**
     * 是否继续处理
     * 当最后一次请求在当前时间 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());
        }
    }

最后的逻辑:

image.png


weiweiyi
1k 声望123 粉丝