From 0398c2fae1b1ab67a749a8ef1da3532d29eb0ce1 Mon Sep 17 00:00:00 2001 From: catbref Date: Sat, 13 Mar 2021 17:03:38 +0000 Subject: [PATCH] Try to avoid clogging up network threads by discarding incoming TRANSACTION messages if we're too busy As importing a transaction requires blockchain lock, all the network threads can be used up blocking for that lock, especially if Synchronizer is active. So we simply discard incoming TRANSACTION messages if we can't immediately obtain the blockchain lock. Some other peer will probably attempt to send the transaction soon again anyway. Plus we swap transaction lists after connection handshake. --- .../java/org/qortal/controller/Controller.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index 16d96fab..cd3cde78 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -1209,6 +1209,18 @@ public class Controller extends Thread { TransactionMessage transactionMessage = (TransactionMessage) message; TransactionData transactionData = transactionMessage.getTransactionData(); + /* + * If we can't obtain blockchain lock immediately, + * e.g. Synchronizer is active, or another transaction is taking a while to validate, + * then we're using up a network thread for ages and clogging things up + * so bail out early + */ + ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock(); + if (!blockchainLock.tryLock()) { + LOGGER.debug(() -> String.format("Too busy to import %s transaction %s from peer %s", transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer)); + return; + } + try (final Repository repository = RepositoryManager.getRepository()) { Transaction transaction = Transaction.fromData(repository, transactionData); @@ -1238,6 +1250,8 @@ public class Controller extends Thread { LOGGER.debug(() -> String.format("Imported %s transaction %s from peer %s", transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer)); } catch (DataException e) { LOGGER.error(String.format("Repository issue while processing transaction %s from peer %s", Base58.encode(transactionData.getSignature()), peer), e); + } finally { + blockchainLock.unlock(); } }