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.Callback;
24 import org.eclipse.jetty.util.LeakDetector;
25 import org.eclipse.jetty.util.log.Log;
26 import org.eclipse.jetty.util.log.Logger;
27
28 public class LeakTrackingConnectionPool extends ConnectionPool
29 {
30 private static final Logger LOG = Log.getLogger(LeakTrackingConnectionPool.class);
31
32 private final LeakDetector<Connection> leakDetector = new LeakDetector<Connection>()
33 {
34 @Override
35 protected void leaked(LeakInfo leakInfo)
36 {
37 LeakTrackingConnectionPool.this.leaked(leakInfo);
38 }
39 };
40
41 public LeakTrackingConnectionPool(Destination destination, int maxConnections, Callback requester)
42 {
43 super(destination, maxConnections, requester);
44 start();
45 }
46
47 private void start()
48 {
49 try
50 {
51 leakDetector.start();
52 }
53 catch (Exception x)
54 {
55 throw new RuntimeException(x);
56 }
57 }
58
59 @Override
60 public void close()
61 {
62 stop();
63 super.close();
64 }
65
66 private void stop()
67 {
68 try
69 {
70 leakDetector.stop();
71 }
72 catch (Exception x)
73 {
74 throw new RuntimeException(x);
75 }
76 }
77
78 @Override
79 protected void acquired(Connection connection)
80 {
81 if (!leakDetector.acquired(connection))
82 LOG.info("Connection {}@{} not tracked", connection, leakDetector.id(connection));
83 }
84
85 @Override
86 protected void released(Connection connection)
87 {
88 if (!leakDetector.released(connection))
89 LOG.info("Connection {}@{} released but not acquired", connection, leakDetector.id(connection));
90 }
91
92 protected void leaked(LeakDetector.LeakInfo leakInfo)
93 {
94 LOG.info("Connection " + leakInfo.getResourceDescription() + " leaked at:", leakInfo.getStackFrames());
95 }
96 }