Skip to content
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

Client reports download status and download details #341

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

michel-laterman
Copy link

Add implementation of downloading status along with download details details as described in open-telemetry/opamp-spec#206

When the client is downloading a package it will report the download status, and report download details (bytes per second and percent download) periodically.

When the client is downloading a package it will report the download
status, and report download details (bytes per second and percent
download) periodically.
@michel-laterman michel-laterman requested a review from a team as a code owner January 10, 2025 22:54
}
}
// start the download reporter
detailsReporter := newDownloadReporter(downloadReporterDefaultInterval, packageLength) // TODO set interval
Copy link
Author

Choose a reason for hiding this comment

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

I need some guidance on where the user of a client library can be expected to set a value for the update interval, or if we even need to expose it

Copy link
Member

@srikanthccv srikanthccv Jan 20, 2025

Choose a reason for hiding this comment

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

I think this should be made configurable by the client

Copy link
Author

@michel-laterman michel-laterman Jan 20, 2025

Choose a reason for hiding this comment

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

Yes, my comment is more about my confusion as to where we should try to pass the config option from; Should we add PackageReporterInterval/SetPackageReporterInterval funcs to the types.PackagesStateProvider interface or does it belong somewhere else?

Copy link
Member

Choose a reason for hiding this comment

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

I think it should be part of StartSettings

Copy link
Author

Choose a reason for hiding this comment

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

StartSettings is not currently being passed to the NewPackagesSyncer function; do we want to add it as another parameter?

Copy link
Member

Choose a reason for hiding this comment

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

NewPackagesSyncer is internal, so passing the interval param should be fine. This is similar to how we enabled heartbeat interval.

@michel-laterman michel-laterman changed the title Client reports download status and download detials Client reports download status and download details Jan 11, 2025
case <-timer.C:
downloadTime := time.Now().Sub(p.start)
downloaded := p.downloaded.Load()
bps := downloaded / uint64(downloadTime/time.Second)
Copy link
Member

Choose a reason for hiding this comment

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

This could cause panic when the downloadTime is less than a second. Also, would make sense to report float instead uint64 for bps precision?

Copy link
Author

@michel-laterman michel-laterman Jan 20, 2025

Choose a reason for hiding this comment

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

I can update the spec for changing the bps to a float: open-telemetry/opamp-spec#210

client/internal/package_download_details_reporter.go Outdated Show resolved Hide resolved
client/internal/package_download_details_reporter.go Outdated Show resolved Hide resolved
}
}
// start the download reporter
detailsReporter := newDownloadReporter(downloadReporterDefaultInterval, packageLength) // TODO set interval
Copy link
Member

@srikanthccv srikanthccv Jan 20, 2025

Choose a reason for hiding this comment

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

I think this should be made configurable by the client

Add feedback from review, not expected to pass until spec changes are
made
// report periodically updates the package status details and calls the passed upateFn to send the new status.
func (p *downloadReporter) report(ctx context.Context, status *protobufs.PackageStatus, updateFn func(context.Context, bool) error) {
go func() {
// Make sure we wait at least 1s before reporting the download rate in bps to avoid a panic
Copy link
Member

Choose a reason for hiding this comment

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

I think having a lower bound of 1s on reporting interval makes sense, but I am not sure I understand the "avoid a panic" comment. What would be panic reason?

Also, downloadReporter.interval is essentially inaccurate by 1 second. Perhaps to make it accurate set the lower bound in newDownloadReporter instead?

}
// start the download reporter
detailsReporter := newDownloadReporter(downloadReporterDefaultInterval, packageLength) // TODO set interval
detailsReporter.report(ctx, status, s.reportStatuses)
Copy link
Member

Choose a reason for hiding this comment

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

Is reportStatuses safe to be called concurrently? The docs don't say it, so I am not sure. Note that reportStatuses calls user-supplied SetLastReportedStatuses which also is not documented to be safe for concurrent call. If you look at the only implementation in InMemPackagesStore I think it is indeed not safe to call concurrently.

if p.packageLength > 0 {
downloadPercent = downloaded / p.packageLength * 100
}
status.DownloadDetails = &protobufs.PackageDownloadDetails{
Copy link
Member

Choose a reason for hiding this comment

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

I am a bit worried that status is a struct owned by someone else and we modify it from our goroutine here, while status's other fields are also simultaneously being modified by the owner. If the code is accidentally modified in the future to modify the same fields we will have a problem.

Can we instead change updateFn to accept the DownloadPercent and DownloadBytesPerSecond as parameters and eliminate the status parameter from downloadReporter? This way the responsibility for getting concurrency correctly will be sole responsibility of the caller of downloadReporter.report instead of being a shared responsibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants