@@ -568,100 +568,135 @@ def update_instance(
568
568
return signal_instance
569
569
570
570
571
- def filter_signal (* , db_session : Session , signal_instance : SignalInstance ) -> bool :
572
- """
573
- Apply filter actions to the signal instance.
574
-
575
- The function first checks if the signal instance is snoozed. If not snoozed,
576
- it checks for a deduplication rule set on the signal instance. If no
577
- deduplication rule is set, a default deduplication rule is applied,
578
- grouping all signal instances together for a 1-hour window, regardless of
579
- the entities in the signal instance.
571
+ def filter_snooze (* , db_session : Session , signal_instance : SignalInstance ) -> SignalInstance :
572
+ """Filters a signal instance for snoozing.
580
573
581
574
Args:
582
575
db_session (Session): Database session.
583
576
signal_instance (SignalInstance): Signal instance to be filtered.
584
577
585
578
Returns:
586
- bool: True if the signal instance is filtered, False otherwise .
579
+ SignalInstance: The filtered signal instance.
587
580
"""
588
-
589
- filtered = False
590
581
for f in signal_instance .signal .filters :
591
582
if f .mode != SignalFilterMode .active :
592
583
continue
593
584
585
+ if f .action != SignalFilterAction .snooze :
586
+ continue
587
+
588
+ if f .expiration .replace (tzinfo = timezone .utc ) <= datetime .now (timezone .utc ):
589
+ continue
590
+
594
591
query = db_session .query (SignalInstance ).filter (
595
592
SignalInstance .signal_id == signal_instance .signal_id
596
593
)
597
594
query = apply_filter_specific_joins (SignalInstance , f .expression , query )
598
595
query = apply_filters (query , f .expression )
596
+ # an expression is not required for snoozing, if absent we snooze regardless of entity
597
+ if f .expression :
598
+ instances = query .filter (SignalInstance .id == signal_instance .id ).all ()
599
599
600
- # order matters, check for snooze before deduplication
601
- # we check to see if the current instances match's it's signals snooze filter
602
- if f .action == SignalFilterAction .snooze :
603
- if f .expiration .replace (tzinfo = timezone .utc ) <= datetime .now (timezone .utc ):
604
- continue
605
-
606
- # an expression is not required for snoozing, if absent we snooze regardless of entity
607
- if f .expression :
608
- instances = query .filter (SignalInstance .id == signal_instance .id ).all ()
609
-
610
- if instances :
611
- signal_instance .filter_action = SignalFilterAction .snooze
612
- filtered = True
613
- break
614
- else :
600
+ if instances :
615
601
signal_instance .filter_action = SignalFilterAction .snooze
616
- filtered = True
617
602
break
603
+ else :
604
+ signal_instance .filter_action = SignalFilterAction .snooze
605
+ break
618
606
619
- elif f .action == SignalFilterAction .deduplicate :
620
- window = datetime .now (timezone .utc ) - timedelta (minutes = f .window )
621
- query = query .filter (SignalInstance .created_at >= window )
622
- query = query .join (SignalInstance .entities ).filter (
623
- Entity .id .in_ ([e .id for e in signal_instance .entities ])
624
- )
625
- query = query .filter (SignalInstance .id != signal_instance .id )
607
+ return signal_instance
626
608
627
- # get the earliest instance
628
- query = query .order_by (asc (SignalInstance .created_at ))
629
- instances = query .all ()
630
609
631
- if instances :
632
- # associate with existing case
633
- signal_instance .case_id = instances [0 ].case_id
634
- signal_instance .filter_action = SignalFilterAction .deduplicate
635
- filtered = True
636
- break
637
- else :
638
- # Check if there's a deduplication rule set on the signal
639
- has_dedup_filter = any (
640
- f .action == SignalFilterAction .deduplicate for f in signal_instance .signal .filters
610
+ def filter_dedup (* , db_session : Session , signal_instance : SignalInstance ) -> SignalInstance :
611
+ """Filters a signal instance for deduplication.
612
+
613
+ Args:
614
+ db_session (Session): Database session.
615
+ signal_instance (SignalInstance): Signal instance to be filtered.
616
+
617
+ Returns:
618
+ SignalInstance: The filtered signal instance.
619
+ """
620
+ for f in signal_instance .signal .filters :
621
+ if f .mode != SignalFilterMode .active :
622
+ continue
623
+
624
+ if f .action != SignalFilterAction .deduplicate :
625
+ continue
626
+
627
+ query = db_session .query (SignalInstance ).filter (
628
+ SignalInstance .signal_id == signal_instance .signal_id
641
629
)
642
- # Apply the default deduplication rule if there's no deduplication rule set on the signal
643
- # and the signal instance is not snoozed
644
- if not has_dedup_filter and not filtered :
645
- default_dedup_window = datetime .now (timezone .utc ) - timedelta (hours = 1 )
646
- instance = (
647
- db_session .query (SignalInstance )
648
- .filter (
649
- SignalInstance .signal_id == signal_instance .signal_id ,
650
- SignalInstance .created_at >= default_dedup_window ,
651
- SignalInstance .id != signal_instance .id ,
652
- SignalInstance .case_id .isnot (None ), # noqa
653
- )
654
- .with_entities (SignalInstance .case_id )
655
- .order_by (desc (SignalInstance .created_at ))
656
- .first ()
630
+ query = apply_filter_specific_joins (SignalInstance , f .expression , query )
631
+ query = apply_filters (query , f .expression )
632
+
633
+ window = datetime .now (timezone .utc ) - timedelta (minutes = f .window )
634
+ query = query .filter (SignalInstance .created_at >= window )
635
+ query = query .join (SignalInstance .entities ).filter (
636
+ Entity .id .in_ ([e .id for e in signal_instance .entities ])
637
+ )
638
+ query = query .filter (SignalInstance .id != signal_instance .id )
639
+
640
+ # get the earliest instance
641
+ query = query .order_by (asc (SignalInstance .created_at ))
642
+ instances = query .all ()
643
+
644
+ if instances :
645
+ # associate with existing case
646
+ signal_instance .case_id = instances [0 ].case_id
647
+ signal_instance .filter_action = SignalFilterAction .deduplicate
648
+ break
649
+ # apply default deduplication rule
650
+ else :
651
+ default_dedup_window = datetime .now (timezone .utc ) - timedelta (hours = 1 )
652
+ instance = (
653
+ db_session .query (SignalInstance )
654
+ .filter (
655
+ SignalInstance .signal_id == signal_instance .signal_id ,
656
+ SignalInstance .created_at >= default_dedup_window ,
657
+ SignalInstance .id != signal_instance .id ,
658
+ SignalInstance .case_id .isnot (None ), # noqa
657
659
)
658
- if instance :
659
- signal_instance .case_id = instance .case_id
660
- signal_instance .filter_action = SignalFilterAction .deduplicate
661
- filtered = True
660
+ .with_entities (SignalInstance .case_id )
661
+ .order_by (desc (SignalInstance .created_at ))
662
+ .first ()
663
+ )
664
+ if instance :
665
+ signal_instance .case_id = instance .case_id
666
+ signal_instance .filter_action = SignalFilterAction .deduplicate
667
+
668
+ return signal_instance
662
669
663
- if not filtered :
670
+
671
+ def filter_signal (* , db_session : Session , signal_instance : SignalInstance ) -> bool :
672
+ """
673
+ Apply filter actions to the signal instance.
674
+
675
+ The function first checks if the signal instance is snoozed. If not snoozed,
676
+ it checks for a deduplication rule set on the signal instance. If no
677
+ deduplication rule is set, a default deduplication rule is applied,
678
+ grouping all signal instances together for a 1-hour window, regardless of
679
+ the entities in the signal instance.
680
+
681
+ Args:
682
+ db_session (Session): Database session.
683
+ signal_instance (SignalInstance): Signal instance to be filtered.
684
+
685
+ Returns:
686
+ bool: True if the signal instance is filtered, False otherwise.
687
+ """
688
+ filtered = False
689
+
690
+ signal_instance = filter_snooze (db_session = db_session , signal_instance = signal_instance )
691
+
692
+ # we only dedupe if we haven't been snoozed
693
+ if not signal_instance .filter_action :
694
+ signal_instance = filter_dedup (db_session = db_session , signal_instance = signal_instance )
695
+
696
+ if not signal_instance .filter_action :
664
697
signal_instance .filter_action = SignalFilterAction .none
698
+ else :
699
+ filtered = True
665
700
666
701
db_session .commit ()
667
702
return filtered
0 commit comments