summaryrefslogtreecommitdiffstats
path: root/server/record.go
blob: 9051146f140d4bb92a4e3712fd5e424379a7c9d0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main

import (
	"time"
)

type Record[T any] struct {
	put       chan<- T
	get       chan<- chan T
	getRecent chan<- chan T
}

type entry[T any] struct {
	t time.Time
	v T
}

func newRecord[T any]() Record[T] {
	put := make(chan T)
	get := make(chan chan T)
	getRecent := make(chan chan T)

	go func() {
		var entries []entry[T]

		for {
			select {
			case v, ok := <-put:
				if !ok {
					return
				}
				entries = append(entries, entry[T]{time.Now(), v})
			case c, ok := <-get:
				if !ok {
					return
				}
				for _, e := range entries {
					c <- e.v
				}
				close(c)
			case c, ok := <-getRecent:
				if !ok {
					return
				}
				if len(entries) > 0 {
					c <- entries[len(entries)-1].v
				}
				close(c)
			}
		}
	}()

	return Record[T]{put, get, getRecent}
}

func (l Record[T]) Close() {
	close(l.put)
	close(l.get)
	close(l.getRecent)
}