1
0
Fork 0
mirror of https://github.com/M66B/FairEmail.git synced 2025-02-22 14:11:00 +00:00

Added connection pool debugging

This commit is contained in:
M66B 2021-07-27 16:17:15 +02:00
parent 6e61c71d48
commit f77a099624
2 changed files with 76 additions and 15 deletions

View file

@ -662,6 +662,14 @@ public class IMAPStore extends Store
} }
try { try {
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("protocolConnect", crumb);
}
boolean poolEmpty; boolean poolEmpty;
synchronized (pool) { synchronized (pool) {
poolEmpty = pool.authenticatedConnections.isEmpty(); poolEmpty = pool.authenticatedConnections.isEmpty();
@ -1144,9 +1152,18 @@ public class IMAPStore extends Store
* releaseStoreProtocol(p); * releaseStoreProtocol(p);
* } * }
*/ */
private IMAPProtocol getStoreProtocol() throws ProtocolException { private IMAPProtocol getStoreProtocol(String reason) throws ProtocolException {
IMAPProtocol p = null; IMAPProtocol p = null;
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("reason", reason);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("getStoreProtocol", crumb);
}
while (p == null) { while (p == null) {
synchronized (pool) { synchronized (pool) {
waitIfIdle(); waitIfIdle();
@ -1230,7 +1247,7 @@ public class IMAPStore extends Store
* Get a store protocol object for use by a folder. * Get a store protocol object for use by a folder.
*/ */
IMAPProtocol getFolderStoreProtocol() throws ProtocolException { IMAPProtocol getFolderStoreProtocol() throws ProtocolException {
IMAPProtocol p = getStoreProtocol(); IMAPProtocol p = getStoreProtocol("getFolderStoreProtocol");
p.removeResponseHandler(this); p.removeResponseHandler(this);
p.addResponseHandler(nonStoreResponseHandler); p.addResponseHandler(nonStoreResponseHandler);
return p; return p;
@ -1317,6 +1334,14 @@ public class IMAPStore extends Store
* Release the protocol object back to the connection pool. * Release the protocol object back to the connection pool.
*/ */
void releaseProtocol(IMAPFolder folder, IMAPProtocol protocol) { void releaseProtocol(IMAPFolder folder, IMAPProtocol protocol) {
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("folder", folder.fullName);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("releaseProtocol", crumb);
}
synchronized (pool) { synchronized (pool) {
if (protocol != null) { if (protocol != null) {
@ -1350,6 +1375,13 @@ public class IMAPStore extends Store
* Release the store connection. * Release the store connection.
*/ */
private void releaseStoreProtocol(IMAPProtocol protocol) { private void releaseStoreProtocol(IMAPProtocol protocol) {
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("releaseStoreProtocol", crumb);
}
// will be called from idle() without the Store lock held, // will be called from idle() without the Store lock held,
// but cleanup is synchronized and will acquire the Store lock // but cleanup is synchronized and will acquire the Store lock
@ -1393,6 +1425,14 @@ public class IMAPStore extends Store
* Release a store protocol object that was being used by a folder. * Release a store protocol object that was being used by a folder.
*/ */
void releaseFolderStoreProtocol(IMAPProtocol protocol) { void releaseFolderStoreProtocol(IMAPProtocol protocol) {
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("releaseFolderStoreProtocol", crumb);
}
if (protocol == null) if (protocol == null)
return; // should never happen return; // should never happen
protocol.removeResponseHandler(nonStoreResponseHandler); protocol.removeResponseHandler(nonStoreResponseHandler);
@ -1411,6 +1451,13 @@ public class IMAPStore extends Store
* Empty the connection pool. * Empty the connection pool.
*/ */
public void emptyConnectionPool(boolean force) { public void emptyConnectionPool(boolean force) {
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("emptyConnectionPool", crumb);
}
synchronized (pool) { synchronized (pool) {
for (int index = pool.authenticatedConnections.size() - 1; for (int index = pool.authenticatedConnections.size() - 1;
@ -1553,7 +1600,7 @@ public class IMAPStore extends Store
throws MessagingException { throws MessagingException {
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("hasCapability");
return p.hasCapability(capability); return p.hasCapability(capability);
} catch (ProtocolException pex) { } catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex); throw new MessagingException(pex.getMessage(), pex);
@ -1566,7 +1613,7 @@ public class IMAPStore extends Store
throws MessagingException { throws MessagingException {
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("getCapability");
Map<String, String> caps = p.getCapabilities(); Map<String, String> caps = p.getCapabilities();
if (caps != null) if (caps != null)
for (String cap : caps.values()) { for (String cap : caps.values()) {
@ -1590,7 +1637,7 @@ public class IMAPStore extends Store
throws MessagingException { throws MessagingException {
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("getCapabilities");
return p.getCapabilities(); return p.getCapabilities();
} catch (ProtocolException pex) { } catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex); throw new MessagingException(pex.getMessage(), pex);
@ -1652,7 +1699,7 @@ public class IMAPStore extends Store
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("isConnected");
p.noop(); p.noop();
} catch (ProtocolException pex) { } catch (ProtocolException pex) {
// will return false below // will return false below
@ -1741,6 +1788,13 @@ public class IMAPStore extends Store
List<IMAPFolder> foldersCopy = null; List<IMAPFolder> foldersCopy = null;
boolean done = true; boolean done = true;
synchronized (pool) {
Map<String, String> crumb = new HashMap<>();
crumb.put("host", host);
crumb.put("connections", Integer.toString(pool.authenticatedConnections.size()));
crumb.put("inuse", Boolean.toString(pool.storeConnectionInUse));
eu.faircode.email.Log.breadcrumb("closeAllFolders", crumb);
}
// To avoid violating the locking hierarchy, there's no lock we // To avoid violating the locking hierarchy, there's no lock we
// can hold that prevents another thread from trying to open a // can hold that prevents another thread from trying to open a
// folder at the same time we're trying to close all the folders. // folder at the same time we're trying to close all the folders.
@ -1924,7 +1978,7 @@ public class IMAPStore extends Store
if (namespaces == null) { if (namespaces == null) {
try { try {
p = getStoreProtocol(); p = getStoreProtocol("getNameSpaces");
namespaces = p.namespace(); namespaces = p.namespace();
} catch (BadCommandException bex) { } catch (BadCommandException bex) {
// NAMESPACE not supported, ignore it // NAMESPACE not supported, ignore it
@ -1983,7 +2037,7 @@ public class IMAPStore extends Store
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("getQuota");
qa = p.getQuotaRoot(root); qa = p.getQuotaRoot(root);
} catch (BadCommandException bex) { } catch (BadCommandException bex) {
throw new MessagingException("QUOTA not supported", bex); throw new MessagingException("QUOTA not supported", bex);
@ -2011,7 +2065,7 @@ public class IMAPStore extends Store
checkConnected(); checkConnected();
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("setQuota");
p.setQuota(quota); p.setQuota(quota);
} catch (BadCommandException bex) { } catch (BadCommandException bex) {
throw new MessagingException("QUOTA not supported", bex); throw new MessagingException("QUOTA not supported", bex);
@ -2098,7 +2152,7 @@ public class IMAPStore extends Store
boolean needNotification = false; boolean needNotification = false;
try { try {
synchronized (pool) { synchronized (pool) {
p = getStoreProtocol(); p = getStoreProtocol("idle");
if (pool.idleState != ConnectionPool.RUNNING) { if (pool.idleState != ConnectionPool.RUNNING) {
// some other thread must be running the IDLE // some other thread must be running the IDLE
// command, we'll just wait for it to finish // command, we'll just wait for it to finish
@ -2238,7 +2292,7 @@ public class IMAPStore extends Store
IMAPProtocol p = null; IMAPProtocol p = null;
try { try {
p = getStoreProtocol(); p = getStoreProtocol("id");
serverParams = p.id(clientParams); serverParams = p.id(clientParams);
} catch (BadCommandException bex) { } catch (BadCommandException bex) {
throw new MessagingException("ID not supported", bex); throw new MessagingException("ID not supported", bex);

View file

@ -280,17 +280,24 @@ public class Log {
} }
} }
static void breadcrumb(String name, String key, String value) { public static void breadcrumb(String name, String key, String value) {
Map<String, String> crumb = new HashMap<>(); Map<String, String> crumb = new HashMap<>();
crumb.put(key, value); crumb.put(key, value);
breadcrumb(name, crumb); breadcrumb(name, crumb);
} }
static void breadcrumb(String name, Map<String, String> crumb) { public static void breadcrumb(String name, Map<String, String> crumb) {
try { try {
StringBuilder sb = new StringBuilder();
sb.append("Breadcrumb ").append(name);
Map<String, Object> ocrumb = new HashMap<>(); Map<String, Object> ocrumb = new HashMap<>();
for (String key : crumb.keySet()) for (String key : crumb.keySet()) {
ocrumb.put(key, crumb.get(key)); String val = crumb.get(key);
sb.append(' ').append(key).append('=').append(val);
ocrumb.put(key, val);
}
if (BuildConfig.DEBUG)
Log.i(sb.toString());
Bugsnag.leaveBreadcrumb(name, ocrumb, BreadcrumbType.LOG); Bugsnag.leaveBreadcrumb(name, ocrumb, BreadcrumbType.LOG);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();