public void doLongPolling(final HttpServletRequest request, final HttpServletResponse response) {
        // compare group md5
        List<ConfigGroupEnum> changedGroup = compareChangedGroup(request);
        String clientIp = getRemoteIp(request);
        // response immediately.
        if (CollectionUtils.isNotEmpty(changedGroup)) {
            this.generateResponse(response, changedGroup);
            LOG.info("send response with the changed group, ip={}, group={}", clientIp, changedGroup);
            return;
        }
        LOG.debug("no changed group, ip={}, waiting for compare cache changed", clientIp);
        // listen for configuration changed.
        final AsyncContext asyncContext = request.startAsync();
        // AsyncContext.settimeout() does not timeout properly, so you have to control it yourself
        asyncContext.setTimeout(0L);
        // block client's thread.
        scheduler.execute(new LongPollingClient(asyncContext, clientIp, HttpConstants.SERVER_MAX_HOLD_TIMEOUT));
    }
@Test
    public void testDoLongPolling() throws UnsupportedEncodingException {
        testCompareChangedGroup();
        testGetRemoteIp();
        testGenerateResponse();
    }