1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.client;
20
21 import org.eclipse.jetty.client.api.Connection;
22 import org.eclipse.jetty.client.api.Destination;
23 import org.eclipse.jetty.util.LeakDetector;
24 import org.eclipse.jetty.util.Promise;
25
26 public class LeakTrackingConnectionPool extends ConnectionPool
27 {
28 private final LeakDetector<Connection> leakDetector = new LeakDetector<Connection>()
29 {
30 @Override
31 protected void leaked(LeakInfo leakInfo)
32 {
33 LeakTrackingConnectionPool.this.leaked(leakInfo);
34 }
35 };
36
37 public LeakTrackingConnectionPool(Destination destination, int maxConnections, Promise<Connection> connectionPromise)
38 {
39 super(destination, maxConnections, connectionPromise);
40 start();
41 }
42
43 private void start()
44 {
45 try
46 {
47 leakDetector.start();
48 }
49 catch (Exception x)
50 {
51 throw new RuntimeException(x);
52 }
53 }
54
55 @Override
56 public void close()
57 {
58 stop();
59 super.close();
60 }
61
62 private void stop()
63 {
64 try
65 {
66 leakDetector.stop();
67 }
68 catch (Exception x)
69 {
70 throw new RuntimeException(x);
71 }
72 }
73
74 @Override
75 protected void acquired(Connection connection)
76 {
77 if (!leakDetector.acquired(connection))
78 LOG.info("Connection {}@{} not tracked", connection, System.identityHashCode(connection));
79 }
80
81 @Override
82 protected void released(Connection connection)
83 {
84 if (!leakDetector.released(connection))
85 LOG.info("Connection {}@{} released but not acquired", connection, System.identityHashCode(connection));
86 }
87
88 protected void leaked(LeakDetector.LeakInfo leakInfo)
89 {
90 LOG.info("Connection " + leakInfo.getResourceDescription() + " leaked at:", leakInfo.getStackFrames());
91 }
92 }