Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

fix pulsar info command to show correct plot size #261

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 44 additions & 22 deletions src/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(crate) struct SummaryUpdateFields {
pub(crate) new_vote_count: u64,
pub(crate) new_reward: Rewards,
pub(crate) new_parsed_blocks: BlockNumber,
pub(crate) maybe_updated_user_space_pledged: Option<ByteSize>,
Copy link
Member

Choose a reason for hiding this comment

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

When would it be None? Or why is Default needed on SummaryUpdateFields?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, it would be None when we are updating other fields like new_vote_count, new_reward etc after reading from subscribed data stream.

if it is not Option type, we would have to query the current space pledged every time we want to update any data inside summary file due to the way the summary file is handled at present.

}

/// Struct for holding the info of what to be displayed with the `info` command,
Expand Down Expand Up @@ -65,18 +66,24 @@ impl SummaryFile {
/// if user_space_pledged is provided, it creates a new summary file
/// else, it tries to open the existing summary file
#[instrument]
pub(crate) async fn new(user_space_pledged: Option<ByteSize>) -> Result<SummaryFile> {
pub(crate) async fn new(maybe_user_space_pledged: Option<ByteSize>) -> Result<SummaryFile> {
let summary_path = summary_path();
let summary_dir = summary_dir();

let mut summary_file;
// providing `Some` value for `user_space_pledged` means, we are creating a new
// file, so, first check if the file exists to not erase its content
if let Some(user_space_pledged) = user_space_pledged {
// File::create will truncate the existing file, so first
// check if the file exists, if not, `open` will return an error
// in this case, create the file and necessary directories
if File::open(&summary_path).await.is_err() {
let file_handle = OpenOptions::new()
.read(true)
.write(true)
.open(&summary_path)
.await
.context("couldn't open existing summary file");
match file_handle {
Err(e) => {
Comment on lines +79 to +80
Copy link
Member

Choose a reason for hiding this comment

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

Why would you still try to write into the file in case of error during opening? I do not understand.

Old code makes not that much sense either. What needs to happen instead is you need to write to a new file and rename it back into intended name. This way you will never get truncated file in the first place.

let user_space_pledged = match maybe_user_space_pledged {
Some(user_space_pledged) => user_space_pledged,
// As per the API contract, if user_space_pledged is None, we only want to open
// existing summary file
None => return Err(e),
};
let _ = create_dir_all(&summary_dir).await;
let _ = File::create(&summary_path).await;
let initialization = Summary {
Expand All @@ -89,34 +96,44 @@ impl SummaryFile {
};
let summary_text =
toml::to_string(&initialization).context("Failed to serialize Summary")?;
summary_file = OpenOptions::new()
let mut summary_file_handle = OpenOptions::new()
.read(true)
.write(true)
.truncate(true)
.open(&summary_path)
.await
.context("couldn't open new summary file")?;
summary_file
summary_file_handle
.write_all(summary_text.as_bytes())
.await
.context("write to summary failed")?;
summary_file.flush().await.context("flush at creation failed")?;
summary_file
summary_file_handle.flush().await.context("flush at creation failed")?;
summary_file_handle
.seek(std::io::SeekFrom::Start(0))
.await
.context("couldn't seek to the beginning of the summary file")?;

return Ok(SummaryFile { inner: Arc::new(Mutex::new(summary_file)) });
Ok(SummaryFile { inner: Arc::new(Mutex::new(summary_file_handle)) })
}
Ok(summary_file_handle) => {
let summary_file = SummaryFile { inner: Arc::new(Mutex::new(summary_file_handle)) };
if let Some(user_space_pledged) = maybe_user_space_pledged {
let (summary, _) = summary_file.read_and_deserialize().await?;
summary_file
.update(SummaryUpdateFields {
is_plotting_finished: summary.initial_plotting_finished,
maybe_updated_user_space_pledged: Some(user_space_pledged),
// No change in other values
new_authored_count: 0,
new_vote_count: 0,
new_reward: Rewards(0),
new_parsed_blocks: 0,
})
Comment on lines +123 to +131
Copy link
Member

Choose a reason for hiding this comment

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

When instantiating structs please order fields in the same exact order as in struct definition, it is confusing otherwise.

.await?;
}
Ok(summary_file)
}
}
// for all the other cases, the SummaryFile should be there
summary_file = OpenOptions::new()
.read(true)
.write(true)
.open(&summary_path)
.await
.context("couldn't open existing summary file")?;
Ok(SummaryFile { inner: Arc::new(Mutex::new(summary_file)) })
}

/// Parses the summary file and returns [`Summary`]
Expand All @@ -140,6 +157,7 @@ impl SummaryFile {
new_vote_count,
new_reward,
new_parsed_blocks,
maybe_updated_user_space_pledged,
}: SummaryUpdateFields,
) -> Result<Summary> {
let (mut summary, mut guard) = self.read_and_deserialize().await?;
Expand All @@ -156,6 +174,10 @@ impl SummaryFile {

summary.last_processed_block_num += new_parsed_blocks;

if let Some(updated_user_space_pledged) = maybe_updated_user_space_pledged {
summary.user_space_pledged = updated_user_space_pledged;
}

let serialized_summary =
toml::to_string(&summary).context("Failed to serialize Summary")?;

Expand Down
2 changes: 2 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async fn update_summary_file_randomly(summary_file: SummaryFile) {
new_vote_count: rng.gen_range(1..10),
new_reward: Rewards(rng.gen_range(1..1000)),
new_parsed_blocks: rng.gen_range(1..100),
maybe_updated_user_space_pledged: Some(ByteSize::gb(rng.gen_range(1..100))),
};
let result = summary_file.update(update_fields).await;
assert!(result.is_ok(), "Failed to update summary file");
Expand Down Expand Up @@ -48,6 +49,7 @@ async fn summary_file_integration() {
new_vote_count: 11,
new_reward: Rewards(1001),
new_parsed_blocks: 101,
maybe_updated_user_space_pledged: Some(ByteSize::gb(1)),
};
summary_file.update(update_fields).await.expect("Failed to update summary file");

Expand Down
Loading