| 437 | } |
| 438 | |
| 439 | func (s *sequenceState) runSequence(e *event.Event) bool { |
| 440 | for i, expr := range s.seq.Expressions { |
| 441 | // only try to evaluate the expression |
| 442 | // if upstream expressions have matched |
| 443 | if !s.next(i) { |
| 444 | if !s.seq.IsUnordered { |
| 445 | continue |
| 446 | } |
| 447 | // it could be the event arrived out |
| 448 | // of order because certain provider |
| 449 | // flushed its buffers first. When this |
| 450 | // happens the event timestamp serves as |
| 451 | // a temporal reference. |
| 452 | // If this sequence expression can evaluate |
| 453 | // against the current event, mark it as |
| 454 | // out-of-order and store in partials list |
| 455 | s.mu.RLock() |
| 456 | ok := expr.IsEvaluable(e) && s.filter.RunSequence(e, i, s.partials, true) |
| 457 | s.mu.RUnlock() |
| 458 | if ok { |
| 459 | s.addPartial(i, e, true) |
| 460 | } |
| 461 | continue |
| 462 | } |
| 463 | |
| 464 | s.mu.RLock() |
| 465 | matches := expr.IsEvaluable(e) && s.filter.RunSequence(e, i, s.partials, false) |
| 466 | s.mu.RUnlock() |
| 467 | |
| 468 | if !matches { |
| 469 | continue |
| 470 | } |
| 471 | |
| 472 | // enforce temporal monotonicity check for ordered sequences |
| 473 | if !s.seq.IsUnordered && !s.lastMatch.IsZero() && !e.Timestamp.After(s.lastMatch) { |
| 474 | // this event is older than or equal to the previous matched slot |
| 475 | continue |
| 476 | } |
| 477 | |
| 478 | // append the partial and transition state machine |
| 479 | s.addPartial(i, e, false) |
| 480 | err := s.matchTransition(i, e) |
| 481 | if err != nil { |
| 482 | matchTransitionErrors.Add(1) |
| 483 | log.Warnf("match transition failure: %v", err) |
| 484 | } |
| 485 | if !s.seq.IsUnordered { |
| 486 | s.lastMatch = e.Timestamp |
| 487 | } |
| 488 | // now try to match all pending out-of-order |
| 489 | // events from downstream sequence slots if |
| 490 | // the previous match hasn't reached terminal |
| 491 | // state |
| 492 | if s.seq.IsUnordered && s.currentState() != sequenceTerminalState { |
| 493 | s.mu.RLock() |
| 494 | for seqID := range s.partials { |
| 495 | for _, evt := range s.partials[seqID] { |
| 496 | if !evt.ContainsMeta(event.RuleSequenceOOOKey) { |