aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/fs4/mplex/ConnectionPool.java
blob: e84adfbef2cb99776aa83d54d80766775b70a787 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.fs4.mplex;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;

import com.yahoo.log.LogLevel;
/**
 * Pool of FS4 connections.
 *
 * @author Tony Vaagenes
 */
public class ConnectionPool {

    private final static int CLEANINGPERIOD = 1000; // Execute every second
    private final Queue<FS4Connection> connections = new ConcurrentLinkedQueue<>();
    private final AtomicInteger activeConnections = new AtomicInteger(0);
    private final AtomicInteger passiveConnections = new AtomicInteger(0);
    private static final Logger log = Logger.getLogger(ConnectionPool.class.getName());

    class PoolCleanerTask extends TimerTask {
        private final ConnectionPool connectionPool;
        public PoolCleanerTask(ConnectionPool connectionPool) {
            this.connectionPool = connectionPool;
        }

        public void run() {
            try {
                connectionPool.dropInvalidConnections();
            } catch (Exception e) {
                log.log(LogLevel.WARNING,
                        "Caught exception in connection pool cleaner, ignoring.",
                        e);
            }
        }
    }

    public ConnectionPool() {
    }

    public ConnectionPool(Timer timer) {
        timer.schedule(new PoolCleanerTask(this), CLEANINGPERIOD, CLEANINGPERIOD);
    }

    private void dropInvalidConnections() {
        for (Iterator<FS4Connection> i = connections.iterator(); i.hasNext();) {
            FS4Connection connection = i.next();
            if (!connection.isValid()) {
                i.remove();
            }
        }
    }

    private FS4Connection registerAsActiveIfNonZero(FS4Connection connection) {
        activeConnections.incrementAndGet();
        passiveConnections.decrementAndGet();
        return connection;
    }

    public FS4Connection getConnection() {
        return registerAsActiveIfNonZero(connections.poll());
    }

    void releaseConnection(FS4Connection connection) {
        assert(connection != null);
        activeConnections.decrementAndGet();
        if (connection.isValid()) {
            passiveConnections.incrementAndGet();
            connections.add(connection);
        }
    }

    void createdConnection() {
        activeConnections.incrementAndGet();
    }

    int activeConnections() {
        return activeConnections.get();
    }

    //unused connections in the pool
    int passiveConnections() {
        return passiveConnections.get();
    }
}