package com.hibegin.http.server.handler;

import com.hibegin.common.util.LoggerUtil;
import com.hibegin.http.server.impl.ServerContext;

import java.net.Socket;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CheckRequestRunnable implements Runnable {

    private static final Logger LOGGER = LoggerUtil.getLogger(CheckRequestRunnable.class);
    private int requestTimeout;
    private Date lastAccessDate;

    private Map<SocketChannel, HttpRequestHandlerThread> channelHttpRequestHandlerThreadMap;
    private ServerContext serverContext;

    public CheckRequestRunnable(int requestTimeout, ServerContext serverContext, Map<SocketChannel, HttpRequestHandlerThread> channelHttpRequestHandlerThreadMap) {
        this.channelHttpRequestHandlerThreadMap = channelHttpRequestHandlerThreadMap;
        this.requestTimeout = requestTimeout;
        this.serverContext = serverContext;
    }

    @Override
    public void run() {
        lastAccessDate = new Date();
        try {
            Set<SocketChannel> removeHttpRequestList = getSocketChannelHttpRequestHandlerThreadMap();
            clearRequestListener(removeHttpRequestList);
            clearRequestDecode(removeHttpRequestList);
        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, "e", e);
        }
    }

    private void clearRequestListener(Set<SocketChannel> removeHttpRequestList) {
        for (SocketChannel socketChannel : removeHttpRequestList) {
            if (channelHttpRequestHandlerThreadMap.get(socketChannel) != null) {
                channelHttpRequestHandlerThreadMap.get(socketChannel).interrupt();
                channelHttpRequestHandlerThreadMap.remove(socketChannel);
            }
        }
    }

    private Set<SocketChannel> getSocketChannelHttpRequestHandlerThreadMap() {
        Map<SocketChannel, HttpRequestHandlerThread> removeHttpRequestList = new HashMap<>();
        for (Map.Entry<SocketChannel, HttpRequestHandlerThread> entry : channelHttpRequestHandlerThreadMap.entrySet()) {
            Socket socket = entry.getKey().socket();
            if (socket.isClosed() || !socket.isConnected()) {
                removeHttpRequestList.put(entry.getKey(), entry.getValue());
            }
            if (requestTimeout > 0) {
                if (System.currentTimeMillis() - entry.getValue().getRequest().getCreateTime() > requestTimeout * 1000) {
                    entry.getValue().getResponse().renderCode(504);
                    removeHttpRequestList.put(entry.getKey(), entry.getValue());
                }
            }
        }
        return removeHttpRequestList.keySet();
    }

    private void clearRequestDecode(Set<SocketChannel> removeHttpRequestList) {
        for (SocketChannel socketChannel : removeHttpRequestList) {
            serverContext.getHttpDeCoderMap().remove(socketChannel);
        }
    }

    public Map<SocketChannel, HttpRequestHandlerThread> getChannelHttpRequestHandlerThreadMap() {
        return channelHttpRequestHandlerThreadMap;
    }

    public Date getLastAccessDate() {
        return lastAccessDate;
    }
}

@@ -78,16 +78,120 @@
 erUtil;%0A
+import com.hibegin.http.server.api.HttpRequestDeCoder;%0Aimport com.hibegin.http.server.api.HttpResponse;%0A
 import c
@@ -325,34 +325,8 @@
 te;%0A
-import java.util.HashMap;%0A
 impo
@@ -361,24 +361,73 @@
 a.util.Set;%0A
+import java.util.concurrent.CopyOnWriteArraySet;%0A
 import java.
@@ -1281,207 +1281,119 @@
     
-Set%3CSocketChannel%3E removeHttpRequestList = getSocketChannelHttpRequestHandlerThreadMap();%0A            clearRequestListener(removeHttpRequestList);%0A            clearRequestDecode(removeHttpRequestList
+clearRequestListener(getClosedRequestChannelSet());%0A            clearRequestDecode(getClosedDecodedChannelSet()
 );%0A 
@@ -1943,48 +1943,31 @@
  get
-SocketChannelHttpRequestHandlerThreadMap
+ClosedRequestChannelSet
 () %7B
@@ -1975,19 +1975,19 @@
         
-Map
+Set
 %3CSocketC
@@ -1996,71 +1996,50 @@
 nnel
-, HttpRequestHandlerThread%3E removeHttpRequestList = new HashMap
+%3E socketChannels = new CopyOnWriteArraySet
 %3C%3E()
@@ -2296,64 +2296,39 @@
     
-removeHttpRequestList.put(entry.getKey(), entry.getValue
+socketChannels.add(entry.getKey
 ());
@@ -2594,68 +2594,519 @@
     
-removeHttpRequestList.put(entry.getKey(), entry.getValue());
+socketChannels.add(entry.getKey());%0A                %7D%0A            %7D%0A        %7D%0A        return socketChannels;%0A    %7D%0A%0A    private Set%3CSocketChannel%3E getClosedDecodedChannelSet() %7B%0A        Set%3CSocketChannel%3E removeHttpRequestList = new CopyOnWriteArraySet%3C%3E();%0A        for (Map.Entry%3CSocketChannel, Map.Entry%3CHttpRequestDeCoder, HttpResponse%3E%3E entry : serverContext.getHttpDeCoderMap().entrySet()) %7B%0A            Socket socket = entry.getKey().socket();%0A            if (socket.isClosed() %7C%7C !socket.isConnected()) %7B
 %0A   
@@ -3110,33 +3110,74 @@
                 
-%7D
+removeHttpRequestList.add(entry.getKey());
 %0A            %7D%0A 
@@ -3225,17 +3225,8 @@
 List
-.keySet()
 ;%0A  

optimize check-request-thread