Apply new notification thresholds only after timeout expires#777
Apply new notification thresholds only after timeout expires#777GyulyVGC merged 13 commits intoGyulyVGC:mainfrom
Conversation
Changes to notifications settings are stored temporarily in temp_notifications field. These are saved to configs only after a timeout has expired. The checking of this timeout and whether there's any new notifications settings to store are done in `TickInit` and `TickRun` arms of `fn update()`.
|
This should close #658. I tried some different approaches but finally decided to put this one up for review since this implementation is the most straightforward one to me, and the one that is the most consistent with existing design. Note that it's not just the notifications thresholds that are instantly applied, but all notifications settings. What do you think? Some things that bother is that the checking whether to update the notifications settings is done for every Tick, and that the very first if-state By the way, when looking at the docs for |
|
Some remarks from a quick review.
|
|
Thank you for the fast review! I'll fix the remaining point you brought up in the coming days and fix the failing test |
|
Now the thresholds are the only notifications settings that aren't applied right away. I went a bit back and forth between what type to store the not yet applied thresholds as, experimenting between using |
|
Haven't re-reviewed the code yet, but I notice an issue by simply testing via running Sniffnet: if I click on the checkbox to enable/disable a specific notification kind, the corresponding notifications are enabled/disabled with some latency... hence I suspect that enabling/disabling is still subject to the timeout. |
|
Thanks! I'll get it fixed and get back to you. I'll see if I can expand the testing to check for this scenario |
|
Thank you! |
|
If the user changes the |
No. The Byte multiplier is part of the threshold and is set via the text input, so its modification has to be subject to timeout. |
|
I've gone with the other approach of storing the temporary thresholds, in a field of type |
|
Is the PR ready for review? |
|
Yes, ready for review :) |
src/gui/sniffer.rs
Outdated
| // Threshold adjustments are saved in `self.temp_thresholds` and then applied | ||
| // after timeout, but for simplicity, this field is always updated to whatever the | ||
| // latest change has been. | ||
| self.update_sound(notification, emit_sound); |
There was a problem hiding this comment.
Do we really need to have all these different methods to update notification values? Can't we merge all of them into one that updates everything except thresholds to make the code more compact?
There was a problem hiding this comment.
Also, I think these could be an impl of Notifications structs rather than Sniffer struct.
There was a problem hiding this comment.
Sure! I tried out different approaches, and went this since although it's quiet verbose, it's very explicit what's going on. Having it in one method looked quiet convoluted in the end when I tried it, but I'll give it another go, I'll probably have some new ideas of how to make it cleaner :)
There was a problem hiding this comment.
I've tried having this an an impl of Notifications instead, but I believe it will make things more complicated. The majority of the code in these methods are to unpack and compare notifications settings and finally potentially apply them immediately. If we put it in impl Notifications we won't be able to apply them, which in my mind would cause an extra layer somewhere else in the code. What do you think?
There was a problem hiding this comment.
Then you can leave it as Sniffer's impl but try to make it just one method that's less verbose
src/gui/sniffer.rs
Outdated
| /// Host data for filter dropdowns (comboboxes) | ||
| pub host_data_states: HostDataStates, | ||
| /// Temporary storage for thresholds while editing. | ||
| pub temp_thresholds: Option<(PacketsNotification, BytesNotification)>, |
There was a problem hiding this comment.
I suggest this to be part of the field TimingEvents::threshold_adjust like (std::time::Instant, Option<(PacketsNotification, BytesNotification)>).
This way you can update it when you call threshold_adjust_now, and you can make was_just_threshold_adjust return an Option instead of bool.
There was a problem hiding this comment.
Good idea, I'll implement this!
|
Thanks for the heads-up! I'll try to get something pushed by the end of the day |
|
I have something in place that is a bit rough but it does what it's supposed to do. Since this latest round is more concerning design, I'm considering slightly polishing what I have and pushing it to hear your thoughts on these changes. What do you think? |
|
IIRC the last time I tested the most recent commit, it was already working fine from a functional perspective. |
|
Not sure why clippy failed in the pipeline for MacOS but not the others (Linux at least fine when I run it locally, but the build was cancelled in the pipeline, I guess since MacOS failed before that). Anyway, clippy for MacOS complains about some code I haven't touched, so you better be the judge of whether it should be changed or ignored. Regarding my latest change, I created one big method that handles all the logic of updating notifications settings and temporary thresholds. Macros could probably decrease the lines of code, but I tried to keep repetition and abstraction layers to a minimum to get your feedback on which way we should go. I'll also add a comment here on GitHub for a function that I think needs some extra attention. |
| } | ||
|
|
||
| /// If timeout has expired, take temporary thresholds | ||
| pub fn threshold_adjust_expired_take( |
There was a problem hiding this comment.
Pretty bad name, but I wanted it to be clear that it mutates the value. Also, the logic is changed, since we want a value to returned/taken if enough time has passed: compared with previous version, where true was returned if not enough time had passed.
There was a problem hiding this comment.
I'd call it was_just_threshold_adjust_take.
There was a problem hiding this comment.
and turn the logic the way round if possible, otherwise leave it as it is
There was a problem hiding this comment.
I don't believe we'll be able to change the behavior of "if timeout has expired, return taken value, else None". If this is the case, I can add a doc string explaining how the method works.
Also, could potentially go with the name was_not_just_threshold_adjust_take, to try and point out the somewhat reversed behavior compared with the other methods since to most people false ~ None, true ~ Some. At the cost of making the name more convoluted.
There was a problem hiding this comment.
I'll think to it and will personally take care of it during the review 👍
|
Thanks will check this out. |
|
Yeah, after updating my toolchain it's failing on Linux as well. A bit odd that it isn't failing for Windows though, but maybe it isn't up to date |
|
On Windows the CI/CD is skipped in PRs since they need a secret environment variable to be set at the repo level (used to download Npcap). |
|
Finally merged 🎉 Thanks mate, I hope I wasn't too pedantic during the process 🤣 @all-contributors please add @vcrn for code |
|
I've put up a pull request to add @vcrn! 🎉 |
Don't worry, you weren't too pedantic, you we're great! 🙂 Really enjoyed this PR and learned some stuff as well. I'll be on the look out for other issues I can help out with. Thanks again for a great app and for all your work! |
Changes to notifications settings are stored temporarily in temp_notifications field. These are saved to configs only after a timeout has expired. The checking of this timeout and whether there's any new notifications settings to store are done in
TickInitandTickRunarms offn update().