Closed ESchouten closed 6 years ago
I am running my application on it now, working like a charm. Much better than the HTTP polling.
My guess why HTTP polling did not work smooth for me: A loadbalancer redirects my requests to different nodes. These nodes did not have the same highest block at all times due to the nature of blockchain and its block publishing. This caused me to receive an event, but when querying the data from the smart contract the data was not always available, probably due to this request being sent to an other node that did not have this block yet.
I have not encountered this problem while connected to the websocket endpoint.
After being connected for +- 30 minutes: o.w.protocol.websocket.WebSocketClient : Closed WebSocket connection to wss://rinkeby.infura.io/ws, because of reason: ''.Conection closed remotely: true
ok so it seems like we would need to manage the connection. making sure it stays up and reset it when the connection is lost
Yeah, testing something now, will report back.
Seems to be less trivial than I thought, I manage to restart the websocket connection, but for some reason the reinstallation of the (block)filter fails, while manual requests are accepted by Infura. Might be some racecondition.
Stacktrace:
2018-10-02 20:58:55.621 INFO 18086 --- [ctReadThread-18] o.w.protocol.websocket.WebSocketClient : Closed WebSocket connection to wss://rinkeby.infura.io/ws, because of reason: ''.Conection closed remotely: true
Oct 02 20:58:56 ip-172-31-12-17 java[18086]: 2018-10-02 20:58:56.072 INFO 18086 --- [tReadThread-223] o.w.protocol.websocket.WebSocketClient : Opened WebSocket connection to wss://rinkeby.infura.io/ws
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: 2018-10-02 20:58:59.782 WARN 18086 --- [pool-3-thread-1] org.web3j.protocol.core.filters.Filter : The filter has not been found. Filter id: 123064189787655064226000680229398265180
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: 2018-10-02 20:58:59.786 ERROR 18086 --- [pool-3-thread-1] org.web3j.protocol.core.filters.Filter : Error sending request
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: org.web3j.protocol.core.filters.FilterException: Error sending request
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.Filter.throwException(Filter.java:176)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.Filter.run(Filter.java:92)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.Filter.reinstallFilter(Filter.java:140)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.Filter.pollFilter(Filter.java:123)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.Filter.lambda$run$0(Filter.java:83)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.lang.Thread.run(Thread.java:748)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: Caused by: java.io.IOException: Interrupted WebSocket request
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.websocket.PropellerWebSocketService.send(PropellerWebSocketService.java:143)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.Request.send(Request.java:71)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.BlockFilter.sendRequest(BlockFilter.java:24)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.core.filters.Filter.run(Filter.java:51)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: ... 10 common frames omitted
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: Caused by: java.lang.InterruptedException: null
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: at org.web3j.protocol.websocket.PropellerWebSocketService.send(PropellerWebSocketService.java:140)
Oct 02 20:58:59 ip-172-31-12-17 java[18086]: ... 13 common frames omitted
so this stack trace comes if you try to reconnect to your filter ?
Since version 3.5.0 web3j automatically tries to re-install/register filters when they are not found by the node. For some reason the subscribe call times out, although the websocket client has been restarted. The websocket is working for other requests, so it might be the case the filter tried to reinstall itself while the websocket connection was not finished setting up.
Web3j 4.0 is planned to have a built-in solution for this: https://github.com/web3j/web3j/issues/703
interesting. I am not sure I get what they say in the issue, is it possible to already use it by implementing the right stuff or do we need to wait for web3j 4.0 ?
To resolve this issue without waiting for web3j 4.0, we could implement something ourselves or wait for the web3j devs to make a fix and build a snapshot.
Fix is not yet present in the latest version of Web3j. Turns out Infura closes websocket connections after 1 hour of inactivity. I am polling my EthAccounts' balance every 15 minutes, and my servers have been online for a day.
Still, an automated recovery of the websocket connection would be a nice-to-have IMO if something would go wrong.
I agree. I hope to get some time for that. Quick question, are you working with java or with scala? I'm thinking more and more of turning this lib up side down and write it with scala and create a java wrapper instead of the other way around
I am actually working with Kotlin, never have worked with scala before. In my experience Kotlin enables developers to write clean and effective code, while forcing best practices and providing features like default null-safety and functional programming among other benefits. Have seen a lot of companies here in the Netherlands switch to Kotlin for their Spring backends for these reasons.
Connect to Infura.io with websockets.
Feedback on my code is appreciated.