-
Notifications
You must be signed in to change notification settings - Fork 246
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
Plotting progress metric added #2525
Conversation
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.
Thanks for your contribution!
If I'm reading this correctly, you want to be able to see total plotting progress in metrics.
While this change likely achieves that (modulo naming, it is not really sector plotting progress, it is total farm plotting progress), there is a better and more scalable way to do this.
Instead of tracking percentages, it is better to have metric about total number of sectors in the farm and number of plotted sectors. While at it, adding tracking of sectors that are about to be replotted would be nice too, that way you will be also visualize how much of the farm is still up to date and how much is being updated.
Also I would appreciate if you read contribution guidelines, but I will clean things up if necessary afterwards anyway. You really do need to clone it locally and test and not just change from the browser though.
I decided to track percentages passed into the on_sector_update callback fn to avoid using the async plotted_sectors_count fn. Is it OK to use asyncs for metrics updating? If no, could you suggest another way? |
You don't need to call |
Well, this will work during initial plotting. But in case of replotting there will be an incorrect result. I assumed that the progress percentage passed via |
Right, that was only about initial plotting. It can be done in various ways, but I'd probably make a separate metrics for replotting. When about-to-expire sectors are identified, metric will increase to that number of sectors and will decrease as sectors are replotted. And similarly for fully expired sectors. Then you can visualize the whole plot as a combination of sectors that are:
|
Can replotting occur during the initial plotting, before all sectors have been plotted at least once? (I hope, NO) |
No, it can't (for the same farm, other farms can be replotting concurrently). It is not even known which sectors are about to expire during initial plotting, but this part will change at some point, so expired sectors will be known before initial plotting is finished (and it would be possible to show in metrics).
Shouldn't be the case right now, if it ever changes we will update the code that relies on this assumption. |
Please review the changes. |
@@ -664,6 +664,11 @@ where | |||
|
|||
info!("Finished collecting already plotted pieces successfully"); | |||
|
|||
for (_, single_disk_farm) in single_disk_farms.iter().enumerate() { | |||
farmer_metrics.update_farm_size(single_disk_farm.id(), single_disk_farm.total_sectors_count() as i64); |
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.
We don't want signed integers here, it should likely be SectorIndex
in size (basically u16
), same for below plotted sectors.
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 i64 is already used in the project on the interface of the established_connections gauge. Should I use the same gauge type and convert values in the updating functions?
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.
Yes, that is what I would prefer. We try to use domain-specific types in various places if possible and convert to the actual types of underlying libraries in case they mismatch at the boundaries.
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.
Is it OK that single_disk_farm.plotted_sectors_count() and single_disk_farm.total_sectors_count() return different types (usize and SectorIndex)?
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.
There are some technical reasons for it, will likely change in the future to the same type
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.
Is it OK to use .try_into().unwrap() for converting in that case?
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 would prefer as
in this particular instance and we don't use .unwrap()
anywhere except tests as contribution guidelines suggest.
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.
So, should I change now?
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'll update it in the upcoming PR
} | ||
} | ||
SectorUpdate::Expiration(SectorExpirationDetails::AboutToExpire) => { | ||
farmer_metrics.update_farm_expired(&single_disk_farm_id, 1); |
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.
This sector is about to expire, but it has not expired yet.
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 we cannot count the Expired and AboutToExpire sectors separately using the incremental counters only, because it isn't possible to determine which sector is replotted within the sector update callback fn. So, I decided to count them together.
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.
We don't need to know "which" sector, we only need to know "how many" and since fully expired sectors are being replotted before those that are about to expire, we already know what to decrement.
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 initially wanted to count expirations and replots cumulatively in the corresponding counter metrics and calculate the difference (actual expired sectors) outside of the farmer, this approach provides a bit more stored data. If you prefer storing only the differences, I can of course change the scheme.
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 see. I guess that would work as well, but I'm not sure what would be more flexible. We already have number of sectors plotted in total with metrics before this PR. I'm open for options either way if there is some additional information to be gained from it.
if let Some(_) = &old_plotted_sector { | ||
farmer_metrics.update_farm_replotted(&single_disk_farm_id, 1); | ||
} else { | ||
farmer_metrics.update_farm_plotted(&single_disk_farm_id, 1); | ||
} |
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.
All new methods are called "update", but most of them are actually increments. "update" is fine, but you then need to pass the new value as the result. Specifically, you track sectors that are about to expire and expired below to increment corresponding values, while here you decrement them, such that at the end of replotting number of expired and about to expire sectors is 0 and number of plotted sectors is the same as total number of sectors.
So most of the metrics will be gauges, not counters.
In order to track those totals you'll want to use AtomicU16
to satisfy Rust's ownership rules.
crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs
Outdated
Show resolved
Hide resolved
pub(super) fn update_farm_size( | ||
&self, | ||
single_disk_farm_id: &SingleDiskFarmId, | ||
sectors: i64, |
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.
sectors: i64, | |
sectors: SectorIndex, |
And if you need to convert it to bigger integer prefer u64::from(sectors)
, this way if some of the types change in incompatible way it'll stop compiling, otherwise as u64
will potentially truncate the data. Just a good practice.
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.
Just updated taking into account all the recommendations
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.
This is good enough, I'll do some changes on top in follow-up PR. Waiting for CI. While waiting for CI please do read contribution guidelines, we have a specific way of introducing changes that would be nice to follow next time.
Well, looks like clippy is not happy, neither is formatting. https://github.com/subspace/subspace/blob/main/CONTRIBUTING.md is your friend, don't check it without actually reading. |
cargo-fmt and cargo-clippy worked locally without problems now. |
Code contributor checklist: