From d9699103b89f8ad4a42feae5ffda52601a3576fd Mon Sep 17 00:00:00 2001 From: woodser Date: Sun, 28 Apr 2024 17:46:32 -0400 Subject: [PATCH] override default rpc timeout with getRpcConnection().setTimeout() --- .../monero/common/MoneroRpcConnection.java | 54 ++++++++++++------- .../java/monero/wallet/MoneroWalletRpc.java | 6 +-- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/main/java/monero/common/MoneroRpcConnection.java b/src/main/java/monero/common/MoneroRpcConnection.java index bd4808ae..91539272 100644 --- a/src/main/java/monero/common/MoneroRpcConnection.java +++ b/src/main/java/monero/common/MoneroRpcConnection.java @@ -72,6 +72,7 @@ public class MoneroRpcConnection { private String password; private String zmqUri; private int priority = 0; + private Long timeoutMs; private Boolean isOnline; private Boolean isAuthenticated; private Long responseTime; @@ -178,10 +179,6 @@ public MoneroRpcConnection setZmqUri(String zmqUri) { this.zmqUri = zmqUri; return this; } - - public int getPriority() { - return priority; - } public MoneroRpcConnection setProxyUri(String proxyUri) { this.proxyUri = proxyUri; @@ -204,6 +201,25 @@ public MoneroRpcConnection setPriority(int priority) { this.priority = priority; return this; } + + public int getPriority() { + return priority; + } + + /** + * Set the RPC request timeout in milliseconds. + * + * @param timeoutMs is the timeout in milliseconds, 0 to disable timeout, or null to use default + * @return this connection + */ + public MoneroRpcConnection setTimeout(Long timeoutMs) { + this.timeoutMs = timeoutMs; + return this; + } + + public Long getTimeout() { + return timeoutMs; + } public MoneroRpcConnection setAttribute(String key, Object value) { attributes.put(key, value); @@ -324,10 +340,10 @@ public Map sendJsonRequest(String method, Object params) { * * @param method is the method to request * @param params are the request's input parameters (supports <Map<String, Object>, List<Object></code>, String, etc) - * @param timeoutInMs is the request timeout in milliseconds + * @param timeoutMs overrides the request timeout in milliseconds * @return the RPC API response as a map */ - public Map sendJsonRequest(String method, Object params, Long timeoutInMs) { + public Map sendJsonRequest(String method, Object params, Long timeoutMs) { CloseableHttpResponse resp = null; try { @@ -340,7 +356,7 @@ public Map sendJsonRequest(String method, Object params, Long ti // send http request HttpPost post = new HttpPost(uri.toString() + "/json_rpc"); - post.setConfig(getRequestConfig(timeoutInMs)); + post.setConfig(getRequestConfig(timeoutMs == null ? this.timeoutMs : timeoutMs)); HttpEntity entity = new StringEntity(JsonUtils.serialize(body)); post.setEntity(entity); Map respMap; @@ -418,10 +434,10 @@ public Map sendPathRequest(String path, Map para * * @param path is the url path of the request to invoke * @param params are request parameters sent in the body - * @param timeoutInMs is the request timeout in milliseconds + * @param timeoutMs overrides the request timeout in milliseconds * @return the request's deserialized response */ - public Map sendPathRequest(String path, Map params, Long timeoutInMs) { + public Map sendPathRequest(String path, Map params, Long timeoutMs) { CloseableHttpResponse resp = null; try { @@ -431,7 +447,7 @@ public Map sendPathRequest(String path, Map para HttpEntity entity = new StringEntity(JsonUtils.serialize(params)); post.setEntity(entity); } - post.setConfig(getRequestConfig(timeoutInMs)); + post.setConfig(getRequestConfig(timeoutMs == null ? this.timeoutMs : timeoutMs)); Map respMap; synchronized (this) { @@ -491,10 +507,10 @@ public byte[] sendBinaryRequest(String path, Map params) { * * @param path is the path of the binary RPC method to invoke * @param params are the request parameters - * @param timeoutInMs is the request timeout in milliseconds + * @param timeoutMs overrides the request timeout in milliseconds * @return byte[] is the binary response */ - public byte[] sendBinaryRequest(String path, Map params, Long timeoutInMs) { + public byte[] sendBinaryRequest(String path, Map params, Long timeoutMs) { // serialize params to monero's portable binary storage format byte[] paramsBin = MoneroUtils.mapToBinary(params); @@ -503,7 +519,7 @@ public byte[] sendBinaryRequest(String path, Map params, Long ti // create http request HttpPost post = new HttpPost(uri.toString() + "/" + path); - post.setConfig(getRequestConfig(timeoutInMs)); + post.setConfig(getRequestConfig(timeoutMs == null ? this.timeoutMs : timeoutMs)); if (paramsBin != null) { HttpEntity entity = new ByteArrayEntity(paramsBin, ContentType.DEFAULT_BINARY); post.setEntity(entity); @@ -554,7 +570,7 @@ public void setPrintStackTrace(boolean printStackTrace) { @Override public String toString() { - return uri + " (uri=" + uri + ", username=" + username + ", password=" + (password == null ? "null" : "***") + ", priority=" + priority + ", isOnline=" + isOnline + ", isAuthenticated=" + isAuthenticated + ", zmqUri=" + zmqUri + ", proxyUri=" + proxyUri + ")"; + return uri + " (uri=" + uri + ", username=" + username + ", password=" + (password == null ? "null" : "***") + ", priority=" + priority + ", timeoutMs=" + timeoutMs + ", isOnline=" + isOnline + ", isAuthenticated=" + isAuthenticated + ", zmqUri=" + zmqUri + ", proxyUri=" + proxyUri + ")"; } @Override @@ -618,12 +634,12 @@ private void validateRpcResponse(Map respMap, String method, Obj throw new MoneroRpcError(errorMsg, code, method, params); } - private RequestConfig getRequestConfig(Long timeoutInMs) { + private RequestConfig getRequestConfig(Long timeoutMs) { RequestConfig.Builder builder = RequestConfig.custom(); - if (timeoutInMs != null) { - builder.setConnectTimeout(Timeout.ofMilliseconds(timeoutInMs)); - builder.setConnectionRequestTimeout(Timeout.ofMilliseconds(timeoutInMs)); - builder.setResponseTimeout(Timeout.ofMilliseconds(timeoutInMs)); + if (timeoutMs != null) { + builder.setConnectTimeout(Timeout.ofMilliseconds(timeoutMs)); + builder.setConnectionRequestTimeout(Timeout.ofMilliseconds(timeoutMs)); + builder.setResponseTimeout(Timeout.ofMilliseconds(timeoutMs)); } return builder.build(); } diff --git a/src/main/java/monero/wallet/MoneroWalletRpc.java b/src/main/java/monero/wallet/MoneroWalletRpc.java index 21082500..f1a50a4b 100644 --- a/src/main/java/monero/wallet/MoneroWalletRpc.java +++ b/src/main/java/monero/wallet/MoneroWalletRpc.java @@ -688,7 +688,7 @@ public MoneroSyncResult sync(Long startHeight, MoneroWalletListenerI listener) { params.put("start_height", startHeight); synchronized(SYNC_LOCK) { // TODO (monero-project): monero-wallet-rpc hangs at 100% cpu utilization if refresh called concurrently try { - Map resp = rpc.sendJsonRequest("refresh", params, 0l); + Map resp = rpc.sendJsonRequest("refresh", params); poll(); Map result = (Map) resp.get("result"); return new MoneroSyncResult(((BigInteger) result.get("blocks_fetched")).longValue(), (Boolean) result.get("received_money")); @@ -737,12 +737,12 @@ public void scanTxs(Collection txHashes) { @Override public void rescanSpent() { - rpc.sendJsonRequest("rescan_spent", 0l); + rpc.sendJsonRequest("rescan_spent"); } @Override public void rescanBlockchain() { - rpc.sendJsonRequest("rescan_blockchain", 0l); + rpc.sendJsonRequest("rescan_blockchain"); } @Override