amichair commented on code in PR #58:
URL: https://github.com/apache/aries-rsa/pull/58#discussion_r3111378953
##########
provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpInvocationHandler.java:
##########
@@ -46,22 +49,105 @@
* which sends the details of the method invocations
* over a TCP connection, to be executed by the remote service.
*/
-public class TcpInvocationHandler implements InvocationHandler {
+public class TcpInvocationHandler implements InvocationHandler, Closeable {
+
+ private static class Connection {
+ Socket socket;
+ BasicObjectOutputStream out;
+ BasicObjectInputStream in;
+
+ public Connection(Socket socket) throws IOException {
+ this.socket = socket;
+ out = new BasicObjectOutputStream(socket.getOutputStream());
+ in = new BasicObjectInputStream(socket.getInputStream());
+ }
+ }
+
private String host;
private int port;
private String endpointId;
private ClassLoader cl;
private int timeoutMillis;
+ private final Deque<Connection> pool = new ArrayDeque<>();
+ private int acquired; // counts connections currently in use (not in pool)
+ private boolean closed;
+
public TcpInvocationHandler(ClassLoader cl, String host, int port, String
endpointId, int timeoutMillis)
- throws UnknownHostException, IOException {
+ throws UnknownHostException, IOException {
this.cl = cl;
this.host = host;
this.port = port;
this.endpointId = endpointId;
this.timeoutMillis = timeoutMillis;
}
+ private Connection acquireConnection() throws IOException {
+ Connection conn;
+ synchronized (pool) {
+ acquired++; // must be first
+ if (closed) {
+ throw new IOException("Connection pool is closed");
+ }
+ conn = pool.pollFirst(); // reuse most recently used connection
+ }
+ // if the pool is empty, create a new connection
+ if (conn == null) {
+ conn = new Connection(openSocket());
+ conn.socket.setSoTimeout(timeoutMillis);
+ conn.socket.setTcpNoDelay(true);
+ conn.in.addClassLoader(cl);
+ conn.out.writeUTF(endpointId); // select endpoint for this
connection
+ }
+ return conn;
+ }
+
+ // must be called exactly once for each call to acquireConnection,
+ // regardless of the outcome - if there was an error, pass null
+ private void releaseConnection(Connection conn) {
+ synchronized (pool) {
+ acquired--; // must be first
+ if (conn != null) {
+ pool.offerFirst(conn); // add to front of queue so old idle
ones can expire
+ }
+ pool.notifyAll();
+ }
+ }
+
+ private void closeConnection(Connection conn) throws IOException {
+ if (conn != null) {
+ conn.socket.close();
+ }
+ }
+
+ private void closeConnections() throws IOException {
+ synchronized (pool) {
+ closed = true; // first prevent acquiring new connections
+ while (true) {
+ // close all idle connections
+ for (Iterator<Connection> it = pool.iterator(); it.hasNext();
) {
Review Comment:
1. No, it calls it.remove()
2. Yes. I'll add a silent catch in closeConnection, there's no point in
throwing it (we want it closed anyway).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]