aboutsummaryrefslogtreecommitdiffstats
path: root/bridge/gitlab/event.go
diff options
context:
space:
mode:
Diffstat (limited to 'bridge/gitlab/event.go')
-rw-r--r--bridge/gitlab/event.go75
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