network connection을 재활용하기 위해 ConnectionPool을 사용합니다.
ConnectionPool의 생성은 아래의 세 property에 의한 초기값을 가지고 생성됩니다.
private static final ConnectionPool systemDefault;
static {
...
systemDefault = new ConnectionPool(...);
}
http.keepAlive: connection을 pool할지 말지 정하는 값. 기본값은 true.
http.keepAliveDuration: pool에 들어와 있는 동안 alive로 고려하는 시간 http.maxConnections: pool에 있을 수 있는 최대 idle connection의 수
http.keepAlive가 false이면 maxIdleConnection의 수를 0으로 해서 ConnectionPool을 만듭니다. pool을 사용하지 않겠다는 이야기가 되겠죠?
pool되는 connection의 관리를 위해 LinkedList를 사용합니다.
private final LinkedList<Connection> connections = new LinkedList<>();
pool에 있다가 더이상 pooling하지 않게된 connection을 지워주기 위한 executor로 ThreadPoolExecutor를 사용합니다. maximumPoolSize를 1로 설정하여 하나의 쓰레드만으로 동작하도록 만듭니다.
pool에서 connection을 찾을 때는 get함수를 사용합니다. 이 함수는 Address를 기준으로 찾습니다. Address가 같지 않거나 alive인 connection이 아니거나 idle 상태로 들어갔거나 하면 다른 connection을 찾습니다. for loop 중간에 list에서 뺄 수도 있으므로 listIterator를 사용합니다.
재활용을 하려는 connection은 recycle 함수에 파라메터로 넣어줍니다. 이때 내부에서 addConnection함수를 호출해주고 addConnection함수는 pool되어 있는 connection들을 clean up하도록 합니다.
clean up하는 connection은 다음과 같습니다.
alive시간이 지난 connection을 clean up을 합니다. 그리고 idle 상태인 connection의 수가 maxIdleConnections를 넘은 경우 오래된 connection부터 찾아서 maxIdleConnections 이하로까지 clean up을 해줍니다.
clean up할 connection이 없는 경우는 wait 상태로 들어갑니다. 이 상태가 풀리는 경우는 addConnection함수가 호출되는 경우입니다.