Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Use a lock instead of atomics for snapshot Progress #11197

Merged
merged 20 commits into from
Oct 28, 2019

Conversation

dvdplm
Copy link
Collaborator

@dvdplm dvdplm commented Oct 23, 2019

After #11178 snapshot::Progress is a bit crowded. This PR sticks the whole struct inside a RwLock.

Not very interesting code here, but this change could use an extra eye or two to ensure I got the lock scope right.

@dvdplm dvdplm self-assigned this Oct 23, 2019
@dvdplm dvdplm added the A1-onice 🌨 Pull request is reviewed well, but should not yet be merged. label Oct 23, 2019
* master:
  Pause pruning while snapshotting (#11178)
  Type annotation for next_key() matching of json filter options (#11192)
  Crypto primitives removed from ethkey (#11174)
  Made ecrecover implementation trait public (#11188)
  Remove unused macro_use. (#11191)
  [dependencies]: jsonrpc `14.0.1` (#11183)
  [receipt]: add `sender` & `receiver` to `RichReceipts` (#11179)
  [dependencies] bump rand 0.7 (#11022)
  [ethcore/builtin]: do not panic in blake2pricer on short input (#11180)
  TxPermissions ver 3: gas price & data (#11170)
  [ethash] chainspec validate `ecip1017EraRounds` non-zero (#11123)
  util Host: fix a double Read Lock bug in fn Host::session_readable() (#11175)
  ethcore client: fix a double Read Lock bug in fn Client::logs() (#11172)
  Aura: Report malice on sibling blocks from the same validator (#11160)
@dvdplm dvdplm added A0-pleasereview 🤓 Pull request needs code review. and removed A1-onice 🌨 Pull request is reviewed well, but should not yet be merged. labels Oct 24, 2019
@dvdplm dvdplm marked this pull request as ready for review October 24, 2019 17:58
@dvdplm dvdplm added A2-insubstantial 👶 Pull request requires no code review (e.g., a sub-repository hash update). M4-core ⛓ Core client code / Rust. and removed A2-insubstantial 👶 Pull request requires no code review (e.g., a sub-repository hash update). labels Oct 24, 2019
Copy link
Collaborator

@ordian ordian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While switching to locks makes the code more readable, there are things to be aware of, like it could introduce unpredictable latencies in a hot path e.g. here and makes it harder to reason about deadlocks (e.g. double lock on read() from the same thread). But it seems to be fine in this case.

ethcore/types/src/snapshot.rs Outdated Show resolved Hide resolved
@ordian ordian added this to the 2.7 milestone Oct 24, 2019
Co-Authored-By: Andronik Ordian <write@reusable.software>
@dvdplm
Copy link
Collaborator Author

dvdplm commented Oct 24, 2019

While switching to locks makes the code more readable

Interesting you think that (I don't, tbh), @ngotchac had a similar comment. Not that it matters much ofc.

I definitely agree that locks are much harder to reason about.

@@ -44,89 +43,68 @@ pub enum Snapshotting {
#[derive(Debug)]
pub struct Progress {
/// Number of accounts processed so far
accounts: AtomicUsize,
accounts: u64,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I like u64 instead usize here

let cur_size = progress.bytes();
if cur_size != last_size {
last_size = cur_size;
let bytes = ::informant::format_bytes(cur_size as usize);
Copy link
Collaborator

@niklasad1 niklasad1 Oct 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will truncate u64 when usize::max_value() < u64::max_value(), I don't know if it is an issue or if we just should change informant::format_bytes to take an u64 instead usize

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usizes here come from the io methods deeper down the stack that actually write bytes; they all return usize for the nr of bytes written. I wanted to be consistent and went with u64 but we can go the other way too if preferred. I don't have a strong opinion tbh.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I don't have strong opinions of this but I think truncation casting deserves a comment because it is not clear to me at least whether it is intended or bug.

Copy link
Collaborator Author

@dvdplm dvdplm Oct 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went the other way in ee4a0a9 ad changed format_bytes() to take a u64 instead.

last_size = cur_size;
let bytes = ::informant::format_bytes(cur_size as usize);
info!("Snapshot: {} accounts (state), {} blocks, {} bytes", p.accounts(), p.blocks(), bytes);
loop {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how much slower this loop would execute w.r.t. reading a RwLock instead of AtomicUsize in each iteration?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully using a RwLock is faster, but I agree, a benchmark providing a hard number would be a good thing. The reason it's (hopefully) faster is there were several atomics getting written to with SeqCst ordering in several places, so having a single lock is hopefully faster.

@dvdplm dvdplm merged commit 0d3423c into master Oct 28, 2019
@dvdplm dvdplm deleted the dp/chore/put-snapshot-progress-behind-rwlock branch October 28, 2019 17:24
dvdplm added a commit that referenced this pull request Nov 6, 2019
* master: (21 commits)
  ropsten #6631425 foundation #8798209 (#11201)
  Update list of bootnodes for xDai chain (#11236)
  ethcore/res: add mordor testnet configuration (#11200)
  [chain specs]: activate `Istanbul` on mainnet (#11228)
  [builtin]: support `multiple prices and activations` in chain spec (#11039)
  Insert explicit warning into the panic hook (#11225)
  Snapshot restoration overhaul (#11219)
  Fix docker centos build (#11226)
  retry on gitlab system failures (#11222)
  Update bootnodes. (#11203)
  Use provided usd-per-eth value if an endpoint is specified (#11209)
  Use a lock instead of atomics for snapshot Progress (#11197)
  [informant]: `MillisecondDuration` -> `as_millis()` (#11211)
  Step duration map configuration parameter ported from the POA Network fork (#10902)
  Upgrade jsonrpc to latest (#11206)
  [export hardcoded sync]: use debug for `H256` (#11204)
  Pause pruning while snapshotting (#11178)
  Type annotation for next_key() matching of json filter options (#11192)
  Crypto primitives removed from ethkey (#11174)
  Made ecrecover implementation trait public (#11188)
  ...
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants