-
-
Notifications
You must be signed in to change notification settings - Fork 12
Analytics tracking enhancements #259
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
base: main
Are you sure you want to change the base?
Conversation
Included some minor refactoring and code cleanup
Also, added missing DLL to Installer
Could not load file or assembly 'System.Text.Json, Version=9.0.0.0'
…by tests Added explicit method to call to report project progress. Included advances in completed stages in project progress analytics
andrew-polk
left a comment
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.
@andrew-polk reviewed 20 files and all commit messages, and made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @tombogle).
src/SayMore/Model/Project.cs line 208 at r1 (raw file):
if (personDelta > 0) properties["PersonsAdded"] = personDelta.ToString();
I guess you don't care about removal of sessions or persons? (assuming that is possible)
Same for media duration below
Deal with race condition to be able to track progress reliably. Remove unnecessary tracking of intermediate updates.
tombogle
left a comment
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.
@tombogle made 1 comment.
Reviewable status: 15 of 20 files reviewed, 1 unresolved discussion (waiting on @andrew-polk).
src/SayMore/Model/Project.cs line 208 at r1 (raw file):
Previously, andrew-polk wrote…
I guess you don't care about removal of sessions or persons? (assuming that is possible)
Same for media duration below
I'm thinking of "progress" as advancing toward some (nebulous) "completion point." While getting rid of cruft can also be a form of progress, it's not the main focus. There are several other things that I could take into account, such as archiving, but that is already a concretely trackable event. My hope is to have an "event" that more-or-less answers the question, did the user make measurable progress toward creation of a finished work during this SayMore session, as opposed to just going in and poking around.
|
Previously, tombogle (Tom Bogle) wrote…
👍 |
andrew-polk
left a comment
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.
@andrew-polk reviewed 5 files and all commit messages, and made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @tombogle).
src/SayMore/Model/Project.cs line 680 at r2 (raw file):
SetAdditionalMetsData
typo
SetAdditionalMetaData
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.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
| public void TrackStatistics(StatisticsViewModel statisticsViewModel) | ||
| { | ||
| if (_statisticsViewModel != null) | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; | ||
|
|
||
| _statisticsViewModel = statisticsViewModel; | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles += FinishedGatheringStatistics; | ||
| if (_statisticsViewModel.IsDataUpToDate) | ||
| { | ||
| // It either finished before we could hook the event, or we hit the race condition. | ||
| FinishedGatheringStatistics(_statisticsViewModel, null); | ||
| } | ||
| } | ||
|
|
||
| private void FinishedGatheringStatistics(object sender, EventArgs e) | ||
| { | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; | ||
| // Check for race condition (see above). | ||
| if (_progressStats != null) | ||
| return; | ||
|
|
||
| _progressStats = new ProgressStats(_statisticsViewModel); | ||
| } |
Copilot
AI
Jan 13, 2026
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 new analytics tracking functionality (TrackStatistics, ReportProgressIfAny, and ProgressStats class) lacks test coverage. Since the repository has comprehensive test coverage for both Project and StatisticsViewModel classes, similar test coverage should be added for these new analytics-related methods to verify correct tracking behavior and edge cases.
| // Check for race condition (see above). | ||
| if (_progressStats != null) | ||
| return; | ||
|
|
||
| _progressStats = new ProgressStats(_statisticsViewModel); |
Copilot
AI
Jan 13, 2026
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.
Potential race condition: _progressStats is accessed from multiple contexts (FinishedGatheringStatistics callback, ReportProgressIfAny, and Dispose) without synchronization. While the null check at line 971 helps, a more robust approach would be to use locking or Interlocked operations to ensure thread-safe access to this field, especially since the statistics gatherer runs on a background thread.
| // Check for race condition (see above). | |
| if (_progressStats != null) | |
| return; | |
| _progressStats = new ProgressStats(_statisticsViewModel); | |
| // Use atomic initialization to avoid race conditions when multiple threads | |
| // access _progressStats concurrently. | |
| var newProgressStats = new ProgressStats(_statisticsViewModel); | |
| if (Interlocked.CompareExchange(ref _progressStats, newProgressStats, null) != null) | |
| { | |
| // Another thread has already initialized _progressStats; discard this instance. | |
| // If ProgressStats implements IDisposable, it should be disposed here. | |
| } |
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.
Pull request overview
Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- src/SayMore/UI/SplashScreenForm.Designer.cs: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public void TrackStatistics(StatisticsViewModel statisticsViewModel) | ||
| { | ||
| if (_statisticsViewModel != null) | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; | ||
|
|
||
| _statisticsViewModel = statisticsViewModel; | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles += FinishedGatheringStatistics; | ||
| if (_statisticsViewModel.IsDataUpToDate) | ||
| { | ||
| // It either finished before we could hook the event, or we hit the race condition. | ||
| FinishedGatheringStatistics(_statisticsViewModel, null); | ||
| } | ||
| } |
Copilot
AI
Jan 13, 2026
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 new TrackStatistics method and analytics tracking logic lack test coverage. Consider adding tests to verify: 1) TrackStatistics is called when StatisticsViewModel is created, 2) ReportProgressIfAny correctly tracks deltas, 3) Analytics.Track is called with expected properties.
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 generally test Analytics code. Given the asyncronous nature of the statistics collection, it's probably not worth the trouble to introduce potentially flaky tests.
tombogle
left a comment
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.
@tombogle made 3 comments and resolved 1 discussion.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @andrew-polk).
src/SayMore/Model/Project.cs line 680 at r2 (raw file):
Previously, andrew-polk wrote…
SetAdditionalMetsData
typo
SetAdditionalMetaData
It really is METS. It's an acronym for Metadata Encoding and Transmission Standard (https://www.loc.gov/standards/mets/)
| public void TrackStatistics(StatisticsViewModel statisticsViewModel) | ||
| { | ||
| if (_statisticsViewModel != null) | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles -= FinishedGatheringStatistics; | ||
|
|
||
| _statisticsViewModel = statisticsViewModel; | ||
| _statisticsViewModel.FinishedGatheringStatisticsForAllFiles += FinishedGatheringStatistics; | ||
| if (_statisticsViewModel.IsDataUpToDate) | ||
| { | ||
| // It either finished before we could hook the event, or we hit the race condition. | ||
| FinishedGatheringStatistics(_statisticsViewModel, null); | ||
| } | ||
| } |
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 generally test Analytics code. Given the asyncronous nature of the statistics collection, it's probably not worth the trouble to introduce potentially flaky tests.
andrew-polk
left a comment
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.
@andrew-polk resolved 1 discussion and dismissed @copilot[bot] from a discussion.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @tombogle).
|
@andrew-polk I've opened a new pull request, #261, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
Sigh. I don't know why copilot did that. Closing it. |
This change is