-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RPC connection failure handling #74
Comments
I developed this code largely by trial-and-error and I remember two lessons learned:
I am not confident that this code as written is definitive or correct. However, it seems to be working for our current use cases with the exception of your complaint about localized messages.
This code is an artifact of my trial-and-error development. As I saw each new message and decided it was "normal" while waiting for a connection I added it to the list of messages to be supressed. An easy way to resolve the output logging issue would be using debug logging and debug level settings. However, I would also like to have a better understanding of which error messages are expected while waiting for a server to start and which ones should be rethrown (if any.) One alternative (only alternative?) to using the message would be to look at the subclasses of SocketException such as
This is what I'm trying to do. Although the
Unfortunately these two cases are not mutually exclusive. Since the server spends time scanning the blockchain before opening the RPC port, there is no way to know you have a correctly specified server until it finished. I know that Bitcoin Core 0.10.x reduces this wait period, but I don't think it is eliminated entirely. I am also unsure how the Omni Core I'm looking forward to seeing how 0.10.x works and seeing if we can reduce the timeout used with |
Ah, that's awesome! While the server is in warmup mode (i.e. still parsing, ...), the error code is -28: if ( e.getMessage().contains("Verifying blocks") ||
e.getMessage().contains("Parsing Omni Layer transactions") ||
e.getMessage().contains("Still scanning.. at block") |
e.getMessage().contains("Loading addresses...")) {
// Swallow
status = e.getMessage();
} Could we make the "waiting for sync/block" smarter, such that it works both ways? |
If there's a consistent error code we should probably use that instead of the strings.
I'm not sure what you mean by 'both ways'. |
Ah, I was referring to this:
|
It would also be great use a lower log level for the waiting messages. It clutters the log:
|
@dexX7 I'm still not sure what you mean by:
|
@msgilligan: when running consensus tests, the local server "waits for sync", until the current block height is reached, but I often see test failures, because the remote server, mostly Chest, is still behind:
This also introduces a chance that not only the height is different, but also the data to compare. What I meant with "both ways": could we wait in a similar manner, until the remote server catches up, too? |
Thanks! There are still two lines, which are shown, when running |
I responded to those comments, but should probably copy those responses here:
|
Good idea. To outline my perspective: I run
This is a very reasonable approach to find a solution. Since 0.0.10, we print the scanning/parsing progress during startup to the console every 30 seconds, but it is also used as "warmup message" for the RPC warmup error messages (-28), so this might be considered here.
Reporting it hundred of times, in any case, seems a bit over the top. if (seconds % MESSAGE_SECONDS == 0) {
log.debug("RPC Status: " + status);
} What if no time based check would be used here, but instead something like: String statusNew;
// ...
if (status != statusNew) {
status = statusNew;
log.debug("RPC Status: " + status);
} ... so that no message is swallowed, but the logs are also not spammed with duplicated messages? Since it wouldn't be hundred of messages anymore, a similar log level might then be used to report "RPC Ready" and "RPC status", like "debug". |
The use case I am most concerned with is running the consensus tests on the Jenkins server. For those tests we remove the Omni state files and it takes ~30 minutes to reach "RPC Ready". Since the jobs run automatically and remotely it is nice to have as detailed a log as possible when reviewing the results. Sometimes I leave a browser window open with the console log in order to monitor the status of the job, so seeing the scrolling status messages is helpful. Also, we generally look at formatted test results when the tests complete and only look at the logs for failures. When I run the tests locally, I do prefer less verbosity -- but, in general, I'd rather have unwanted verbosity locally than miss critical information when a test fails on Jenkins. I like your I also think we should try to follow the semantic guidelines for the logging levels, so that when they are configured to run at a particular level the behavior makes sense. We can then set a default level in the Gradle file that makes sense. I believe that logging level can also be modified for a specific Java pakage, e.g. The current levels pretty much conform to my understanding of the meanings of the various levels, though I know there a particular cases that I know or wrong and I am certainly open to suggestions. If I understand your preferences correctly, I think you prefer logging at the |
I'm pretty sure slf4j uses log4j logging level, defined in Level INFO:
DEBUG:
|
Currently
Hehe sorry again, I wasn't clear: I'm interested in the test results and test progress, but I'm not interested in the RPC initialization, which I'd consider "one level below". If we say that progress messages are
At this point I would disagree, and consider "RPC Status" as more important than "RPC Ready". The |
I'm reluctant to use the I'm hoping we can make it work with just
I see your point.
Removed. See aff3cbc. |
@dexX7 Is this one completed in your opinion? Can we close it? |
Yup, was resolved by #89. |
In BitcoinClient.java#L61-L67, when waiting for the server, and a
SocketException
is caught, then the stack trace should not be dumped, if certain certain expected exception messages are identified. This is pretty straight forward, to suppress errors while waiting.However, those messages are localized, even without
getLocalizedMessage()
, and this causes a lot of output.Could we replace those checks and suppress all
ConnectException
? Or is there an alternative to using the exception messages?From an user's point of view, there are probably three relevant outcomes in this context, which should be handled differently:
A failed authorization can be identified as
JsonRPCException
withhttpCode = 401
, but the other two are probably more tricky: a refused connection expresses itself asConnectException
, but I was unable to see "waiting" in action.The text was updated successfully, but these errors were encountered: