-
Notifications
You must be signed in to change notification settings - Fork 12
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
Set BlockchainBridge
free from blocking caused by RPC calls
#744
Comments
BlockchainBridge
Free From Being Blocked by RPC Calls
BlockchainBridge
Free From Being Blocked by RPC CallsBlockchainBridge
Free From Blocking Caused by RPC Calls
BlockchainBridge
Free From Blocking Caused by RPC CallsBlockchainBridge
free from blocking caused by RPC calls
@Syther007 and I were working on this card for some time and have figured out some issues with the current design.
Programming Design Issues:
|
How we use the methods for
RPC
calls from theWeb3
library is unfortunate. Instead of treating them as how they are intended to, we call a method on them all, without an exception, whose processing squeezes the whole actor. It is a method that, in case of unanticipated events, prevents the Actor from making progress by finishing the currently started message and picking another from the Actor's mailbox.These methods return Futures, as it is desirable for code like this to run asynchronously, however, we give up on the benefits and don't drain the potential of it out really. Instead, we call
.wait()
on the created Futures and therefore we deliberately choose to block the local thread and wait up until whatever data comes back from the remote server.That opens up space for bad events:
If the blockchain service provider is down for any reason, our call won't resolve until their services recover. It can evidently take an indeterminate amount of time. Even though there is an argument that if the blockchain interface becomes unavailable for one call the connection will probably be useless for any kind of blockchain RPC which we use and therefore the fact it's blocking isn't causing any active damage by preventing something what could have been used otherwise. It cannot.
From the optics of the user's experience all actions the BlockchainBridge can perform on an order of the user will look unresponsive. The first call that has stuck and is causing blocking will takes up all the capacities of this actor. The worse, the ongoing handling of this particular actor message is being prolonged and therefore no other message can reach its turn.
The actor has its own Mailbox. If anybody sends a new message to this actor it will languish in its mailbox without a chance to be picked and played. For the BlockchainBridge, it is, I believe, exclusively the Accountant who supplies it with messages (even if the need arises elsewhere, the Accountant is always the last piece of the chain and the producer of that message). Fortunately, these message are always "just" the scan requests, so the global effect is that scanning has stopped functioning and therefore the given Node is nearing a ban from other Nodes.
Another, but less severe observable phenomenon would come from the Websocket messages. This is because the user is given (under the standard circumstances) the ability to provoke the scans by a command. In this situation, though, these executed commands wouldn't bring fruits back. No immediate scanning starts. All it does is another actor message to ask for a scan put in the BlockchainBridge Mailbox. We also can see that the user's order would necessarily time out soon, because no response turned up, and information about that would be displayed.
We need to get away from this disadvantageous situation. For example, we have a record of a card that aims at making it possible to change the blockchain interface service provider during runtime #738. If feasible, we'd appreciate that functionality in our situation. If it allows to switch from a provider that is out of service to another which works fine. In order to be able to that, we'd definitely have to function without the blocking, which means we would employ true asynchronous mechanism and let the Actor have free hands for proper maintenance of the queue with waiting messages. This might be a bit complicated but not terribly.
Anyway, we believe it's advisable to put this task off and focus on the cards that will make our codebase understand the new
async/await
concept. (A good start is this one #676) We could otherwise easily wast time on reworking the same area of code twice, now, with the out-fashioned chain-like Futures, and later when makingasync/await
code out of it.The text was updated successfully, but these errors were encountered: