diff options
Diffstat (limited to 'bridge/gitlab/event.go')
-rw-r--r-- | bridge/gitlab/event.go | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/bridge/gitlab/event.go b/bridge/gitlab/event.go index 875b3cf4..80663edd 100644 --- a/bridge/gitlab/event.go +++ b/bridge/gitlab/event.go @@ -2,7 +2,6 @@ package gitlab import ( "fmt" - "sort" "strings" "time" @@ -42,6 +41,8 @@ const ( EventMentionedInMergeRequest ) +var _ Event = &NoteEvent{} + type NoteEvent struct{ gitlab.Note } func (n NoteEvent) ID() string { return fmt.Sprintf("%d", n.Note.ID) } @@ -108,6 +109,8 @@ func (n NoteEvent) Title() string { return text.CleanupOneLine(n.Body) } +var _ Event = &LabelEvent{} + type LabelEvent struct{ gitlab.LabelEvent } func (l LabelEvent) ID() string { return fmt.Sprintf("%d", l.LabelEvent.ID) } @@ -124,6 +127,8 @@ func (l LabelEvent) Kind() EventKind { } } +var _ Event = &StateEvent{} + type StateEvent struct{ gitlab.StateEvent } func (s StateEvent) ID() string { return fmt.Sprintf("%d", s.StateEvent.ID) } @@ -140,6 +145,8 @@ func (s StateEvent) Kind() EventKind { } } +var _ Event = &ErrorEvent{} + type ErrorEvent struct { Err error Time time.Time @@ -150,28 +157,50 @@ func (e ErrorEvent) UserID() int { return -1 } func (e ErrorEvent) CreatedAt() time.Time { return e.Time } func (e ErrorEvent) Kind() EventKind { return EventError } -// SortedEvents consumes an Event-channel and returns an event slice, sorted by creation date, using CreatedAt-method. -func SortedEvents(c <-chan Event) []Event { - var events []Event - for e := range c { - events = append(events, e) - } - sort.Sort(eventsByCreation(events)) - return events -} - -type eventsByCreation []Event - -func (e eventsByCreation) Len() int { - return len(e) -} - -func (e eventsByCreation) Less(i, j int) bool { - return e[i].CreatedAt().Before(e[j].CreatedAt()) -} - -func (e eventsByCreation) Swap(i, j int) { - e[i], e[j] = e[j], e[i] +// SortedEvents fan-in some Event-channels into one, sorted by creation date, using CreatedAt-method. +// This function assume that each channel is pre-ordered. +func SortedEvents(inputs ...<-chan Event) chan Event { + out := make(chan Event) + + go func() { + defer close(out) + + heads := make([]Event, len(inputs)) + + // pre-fill the head view + for i, input := range inputs { + if event, ok := <-input; ok { + heads[i] = event + } + } + + for { + var earliestEvent Event + var originChannel int + + // pick the earliest event of the heads + for i, head := range heads { + if head != nil && (earliestEvent == nil || head.CreatedAt().Before(earliestEvent.CreatedAt())) { + earliestEvent = head + originChannel = i + } + } + + if earliestEvent == nil { + // no event anymore, we are done + return + } + + // we have an event: consume it and replace it if possible + heads[originChannel] = nil + if event, ok := <-inputs[originChannel]; ok { + heads[originChannel] = event + } + out <- earliestEvent + } + }() + + return out } // getNewTitle parses body diff given by gitlab api and return it final form |