-
Notifications
You must be signed in to change notification settings - Fork 720
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
cardano-testnet: Waiting for blocks using EpochStateView
.
#5836
cardano-testnet: Waiting for blocks using EpochStateView
.
#5836
Conversation
14c8e77
to
57828c1
Compare
EpochStateView
.
EpochStateView
.EpochStateView
.
5c2bfe4
to
1bbdef6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! This will make tests much simpler. I just added a couple of ideas for small simplifications
d52dc11
to
eb553cc
Compare
91a28a8
to
84f3489
Compare
Co-authored-by: Pablo Lamela <[email protected]>
84f3489
to
7e0c341
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
, socketPath :: !SocketPath | ||
, epochStateView :: !(IORef (Maybe AnyNewEpochState)) | ||
-- ^ node socket path, to which foldEpochState is connected to | ||
, wakeLock :: !(TChan ()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was wrong with the IORef
? If we are going to use TChan
s and TMVar
s there needs to be good justification for doing so. I don't immediately see the benefit of this increased complexity in an already tedious testing environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal here is to listen to changes of EpochStateView
. You can't do this just using IORef
. You could do this using MVar
, and having watching threads block on empty MVar
and continue when MVar
gets filled. But then you still need additional IORef
for functions checking for current EpochStateView
without blocking. The problem with using MVar
and IORef
at the same time, is that you don't have any guarantees about the order of operations in the listening thread. In other words, If you update IORef
and MVar
in order in one thread, the other threads may see it in a different order. This means that listeners waiting on MVar ()
may see stale IORef
value.
I've chosen STM
which gives you a single view on both of variables, but you don't have MVar
analogue for waiting in multiple threads for an update of a single MVar
. (TMVar
is only single-wakeup).
If we want to avoid STM here, we can define view and lock:
, wakeLock :: !(MVar (AnyNewEpochState, SlotNo, BlockNo))
, epochStateView :: !(IORef (AnyNewEpochState, SlotNo, BlockNo))
assuming we won't use one value to check the other, because they can be out-of-sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to notify the listeners about changes? I could understand wanting to notify listeners of changes if the changes are short lived but they are not (or at least I can't think of any that are). What problem is this solving? Why specifically do we need this level of granularity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an alternative to watchEpochStateView
which is polling every 100ms EpochStateView
. Sometimes new epoch state is updated much slower, like once every few seconds. So it saves some CPU on needlessly computing the check again and again on the same input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the additional complexity is not worth it. We should be using the atomic*
versions of the IORef
functions to avoid race conditions/partial writes etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you can't implement blocking and waiting or multi-wakeup using just IORef
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you feel that MVar
s are too much, I can rewrite this PR using polling in watchEpochStateView
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you can't implement blocking and waiting or multi-wakeup using just IORef.
Why do we need this? If the goal is to "listen to changes of EpochStateView" and your reason is:
It's an alternative to watchEpochStateView which is polling every 100ms EpochStateView. Sometimes new epoch state is updated much slower, like once every few seconds. So it saves some CPU on needlessly computing the check again and again on the same input.
I say the complexity is not worth it. The changes we are interested in don't require this level of granularity. Saving a little bit of CPU does not justify the additional complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting on MVar
is not that much more complex than polling. I'll rewrite the PR using polling then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one I wrote already uses polling, you can use that one, or tune it
Superseded by #5843 |
Description
This PR provides new functions allowing to extract slot number and block number from epoch state view, and additionally wait for epoch state view updates. This cuts down the test execution time a bit. Waiting for an epoch in a plutus test takes ~70s, where one block wait is around 20s.
This PR is stacked on top of #5835
watchEpochStateUpdate
was inspired by @palas 'swatchEpochStateUpdate
function in #5830 , but it usesTChan
for waiting for an update, instead of polling.Checklist
See Runnings tests for more details
CHANGELOG.md
for affected package.cabal
files are updatedhlint
. See.github/workflows/check-hlint.yml
to get thehlint
versionstylish-haskell
. See.github/workflows/stylish-haskell.yml
to get thestylish-haskell
versionghc-8.10.7
andghc-9.2.7
Note on CI
If your PR is from a fork, the necessary CI jobs won't trigger automatically for security reasons.
You will need to get someone with write privileges. Please contact IOG node developers to do this
for you.