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

Add group_names qs method for Acknowledgement list #838

Merged
merged 5 commits into from
Jul 24, 2024

Conversation

podliashanyk
Copy link
Contributor

For Uninett/argus-htmx-frontend#25

NB!

The query is likely not as efficient as it could be. Help wanted.

@podliashanyk podliashanyk added the help wanted Extra attention is needed label Jun 27, 2024
@podliashanyk podliashanyk requested review from a team June 27, 2024 13:33
@podliashanyk podliashanyk self-assigned this Jun 27, 2024
@codecov-commenter
Copy link

codecov-commenter commented Jun 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.73%. Comparing base (cdc23e5) to head (6423868).
Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #838      +/-   ##
==========================================
- Coverage   84.81%   83.73%   -1.08%     
==========================================
  Files          76       72       -4     
  Lines        3846     3567     -279     
==========================================
- Hits         3262     2987     -275     
+ Misses        584      580       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

github-actions bot commented Jun 27, 2024

Test results

    7 files    553 suites   21m 57s ⏱️
  449 tests   448 ✅ 1 💤 0 ❌
3 143 runs  3 136 ✅ 7 💤 0 ❌

Results for commit 6423868.

♻️ This comment has been updated with latest results.

Comment on lines 509 to 511
def acked_by(self, group: str):
return Acknowledgement.objects.filter(event__incident=self, event__actor__groups__name=group).exists()

Copy link
Contributor

Choose a reason for hiding this comment

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

Since everything else here seems to be a property, i guess this should be too?

Copy link
Contributor

Choose a reason for hiding this comment

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

It cannot be a property, when I try to add it I get the error "Remove 1 parameters; property getter methods receive only "self"."

Copy link
Contributor

Choose a reason for hiding this comment

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

ah yeah true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

group parameter is a must here, can't remove it. Without it I would just use an already existing acked property. But maybe acked_by should be moved to other model, say IncidentQuerySet?

Copy link
Member

Choose a reason for hiding this comment

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

group parameter is a must here, can't remove it. Without it I would just use an already existing acked property. But maybe acked_by should be moved to other model, say IncidentQuerySet?

Since this is a boolean check for a single incident, that makes no sense. Keep it here, but rename to is_acked_by to signify that it's a boolean check (and yes, since it takes arguments, it cannot be a property).

If you want a query that filters a set of incidents based on group acknowledgement, that's when you want a method on the IncidentQuerySet

Copy link
Contributor

Choose a reason for hiding this comment

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

Acknowledgment has the queryset method active() to find non-expired acks.

Incident.acks.active() gets non-expired acks on a specific incident. You could also have a queryset method on Acknowledgment that spits out a set of group names instead of actual acks, so, in code: "noc" in Incident.acks.active().group_names(). For templates you could have a filter acked_by_group which runs the previous code internally.

Copy link
Contributor

@hmpf hmpf Jul 5, 2024

Choose a reason for hiding this comment

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

In the actual incident list it will be necessary to always prefetch() events and acks and for geant also groups. Whether we should always prefetch grousp or toggle it somehow... yet another setting?

Copy link
Collaborator

@elfjes elfjes Jul 5, 2024

Choose a reason for hiding this comment

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

Incident.acks.active() gets non-expired acks on a specific incident. You could also have a queryset method on Acknowledgment that spits out a set of group names instead of actual acks, so, in code: "noc" in Incident.acks.active().group_names(). For templates you could have a filter acked_by_group which runs the previous code internally.

That, joined with ack groups sounds like a simpler way than using an acked_by() method (be sure to prefetch acks and groups tho like you said)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for suggestions @lunkwill42, @elfjes, @hmpf! 🙌

Landed on the following solution:
Since acks-by-group info is so far only relevant for https://github.com/Uninett/argus-htmx-frontend, the pre-fetches will be added in Uninett/argus-htmx-frontend#25. Ditto settings for toggling prefetch of group info.

Will reuse existing qs methods for acknowledgment list and add a new one for fetching user_groups.

Created #843 for further optimization if we see that pre-fetch and existing methods aren't sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is_acked_by is no longer necessary, just the group_names one

src/argus/incident/models.py Outdated Show resolved Hide resolved
Copy link
Member

@lunkwill42 lunkwill42 left a comment

Choose a reason for hiding this comment

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

Good enough for me - but beware my comments about how this will actually be used. Calling it repeatedly for a list of incidents is not good (tm) :)

Copy link
Contributor

@hmpf hmpf left a comment

Choose a reason for hiding this comment

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

You'll need a tiny test as well.

Comment on lines 509 to 511
def is_acked_by(self, group: str) -> bool:
return Acknowledgement.objects.filter(event__incident=self, event__actor__groups__name=group).exists()

Copy link
Contributor

Choose a reason for hiding this comment

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

You need to check if it has expired...

Do that and return False early if it has.

Also, you could probably reuse the property "acks", like so:

return self.acks.filter(event__actor__groups__name=group).exists()

(Both "acks" and "acked" need a refactor, frankly. Needs its own issue.)

Copy link
Contributor

Choose a reason for hiding this comment

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

You could also just rename it to "has_been_acked_by" and ignore expiration.

Copy link
Contributor

Choose a reason for hiding this comment

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

(The best solution is denormalizing, having whether this is a current ack on the incident itself, but that doesn't help in this specific case. we should not have a database field on incident for every not-expired ack per group...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will stick to is_acked_by and check if ack has expired

@johannaengland
Copy link
Contributor

You'll need a tiny test as well.

If you need help with that @podliashanyk, I can be of assistance :)

Comment on lines 509 to 512
def is_acked_by(self, group: str) -> bool:
ack_not_expired_query = Q(expiration__isnull=True) | Q(expiration__gt=timezone.now())
return self.acks.filter(ack_not_expired_query, event__actor__groups__name=group).exists()

Copy link
Contributor

Choose a reason for hiding this comment

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

def is_acked_by(self, groupname: str) -> bool:
    acks = self.acks.active()
    return acks.filter(event__actor__groups__name=groupname).exists()

@hmpf hmpf self-requested a review July 5, 2024 11:54
Copy link

sonarcloud bot commented Jul 5, 2024

@podliashanyk podliashanyk changed the title Add acked_by helper to incident model Add group_names qs method for Acknowledgement list Jul 5, 2024
@hmpf hmpf added the demo Must work for demo label Jul 23, 2024
@hmpf hmpf merged commit 52eb2b3 into master Jul 24, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
demo Must work for demo help wanted Extra attention is needed
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants