/
lib.go
137 lines (107 loc) · 2.39 KB
/
lib.go
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package lib
import (
"context"
"encoding/json"
"net/http"
"sort"
"time"
)
// ---------------------------------------------------------------------
// Interfaces
type Reactor interface {
Receive(at time.Time, from string, event InEvent) []OutEvent
Tick(at time.Time) []OutEvent
Timer(at time.Time) []OutEvent
Init() []OutEvent
}
type Marshaler interface {
UnmarshalRequest(request string, input json.RawMessage, output *Request) error
UnmarshalMessage(message string, input json.RawMessage, output *Message) error
}
// ---------------------------------------------------------------------
// Types
type MetaInfo struct {
TestId TestId `json:"test-id"`
RunId RunId `json:"run-id"`
LogicalTime int `json:"logical-time"`
}
type ScheduledEvent struct {
At time.Time
From string
To string
Event InEvent
Meta MetaInfo
}
type InEvent interface{ InEvent() }
type ClientRequest struct {
Id uint64
Request Request
}
type Request interface {
RequestEvent() string
}
func (_ ClientRequest) InEvent() {}
type InternalMessage struct {
Message Message `json:"message"`
}
func (im InternalMessage) MessageEvent() string {
return im.Message.MessageEvent()
}
func (im InternalMessage) MarshalJSON() ([]byte, error) {
return json.Marshal(im.Message)
}
type Message interface {
MessageEvent() string
}
func (_ InternalMessage) InEvent() {}
type Args interface{ Args() }
type ClientResponse struct {
Id uint64 `json:"id"`
Response Response `json:"response"`
}
func (c ClientResponse) ResponseEvent() string {
return c.Response.ResponseEvent()
}
type Response interface {
ResponseEvent() string
}
type Timer struct {
Duration time.Duration `json:"duration"`
}
func (_ ClientResponse) Args() {}
func (_ InternalMessage) Args() {}
func (_ Timer) Args() {}
type Receiver = string
func Singleton(to Receiver) []Receiver {
return Set(to)
}
func Set(to ...Receiver) []Receiver {
sort.Strings(to)
return to
}
type OutEvent struct {
To []Receiver // Assumed to be a set.
Args Args
}
// ---------------------------------------------------------------------
var quit chan struct{}
func Setup(f func()) {
quit = make(chan struct{})
go loop(f)
}
func Teardown(srv *http.Server) {
close(quit)
if err := srv.Shutdown(context.Background()); err != nil {
panic(err)
}
}
func loop(f func()) {
for {
select {
case <-quit:
return
default:
f()
}
}
}