142 lines
2.8 KiB
Go
142 lines
2.8 KiB
Go
package events
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
// ErrorLevel is the level of the ServerError
|
|
type ErrorLevel string
|
|
|
|
// Status is the status of an event
|
|
type Status string
|
|
|
|
// Different ErrorLevels and statuses
|
|
const (
|
|
// ErrorLevel
|
|
WarningError ErrorLevel = "warning"
|
|
FatalError ErrorLevel = "fatal"
|
|
// Statuses
|
|
OK Status = "ok"
|
|
Error Status = "error"
|
|
)
|
|
|
|
// Event is the base of a message
|
|
type Event struct {
|
|
Type string `json:"type"`
|
|
Status Status `json:"status"`
|
|
}
|
|
|
|
// ClientMessage represents a message sent by the client
|
|
type ClientMessage struct {
|
|
Event
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// ServerEvent represents an event sent to the client
|
|
type ServerEvent struct {
|
|
Event
|
|
Data interface{} `json:"message"`
|
|
}
|
|
|
|
// ErrorEvent represents an event error
|
|
type ErrorEvent struct {
|
|
Level ErrorLevel `json:"level"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// ServerError represents an error sent to the client
|
|
type ServerError struct {
|
|
Event
|
|
ErrorEvent `json:"error"`
|
|
}
|
|
|
|
// Eventer define an interface that any eventer must follow
|
|
type Eventer interface {
|
|
Subscribe(func())
|
|
Unsubscribe()
|
|
Launch()
|
|
Name() string
|
|
}
|
|
|
|
// Notifier represents the base of any Eventer
|
|
// Notify implements Subscribe and Unsubscribe methods
|
|
type Notifier struct {
|
|
sync.RWMutex
|
|
subscribed bool
|
|
done chan struct{}
|
|
eventStream chan ServerEvent
|
|
errorStream chan ServerError
|
|
}
|
|
|
|
// NewNotifier returns a new notifier
|
|
func NewNotifier(eventStream chan ServerEvent, errorStream chan ServerError) *Notifier {
|
|
return &Notifier{
|
|
eventStream: eventStream,
|
|
errorStream: errorStream,
|
|
done: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
// Subscribe subscribes a client on the Notifier
|
|
func (t *Notifier) Subscribe(launch func()) {
|
|
t.Lock()
|
|
defer t.Unlock()
|
|
|
|
// Check if already subscribed
|
|
if t.subscribed {
|
|
return
|
|
}
|
|
t.subscribed = true
|
|
|
|
go launch()
|
|
}
|
|
|
|
// Unsubscribe unsubscribes a client from receiving any more events from
|
|
// the Notifier
|
|
func (t *Notifier) Unsubscribe() {
|
|
t.Lock()
|
|
defer t.Unlock()
|
|
|
|
// Check if already unsubscribed
|
|
if !t.subscribed {
|
|
return
|
|
}
|
|
t.subscribed = false
|
|
|
|
t.done <- struct{}{}
|
|
}
|
|
|
|
// Error sends an error into the errorStream channel
|
|
func (t *Notifier) Error(name string, err error) {
|
|
t.errorStream <- ServerError{
|
|
Event: Event{
|
|
Type: name,
|
|
Status: Error,
|
|
},
|
|
ErrorEvent: ErrorEvent{
|
|
Level: WarningError,
|
|
Message: err.Error(),
|
|
},
|
|
}
|
|
}
|
|
|
|
// FatalError sends an error into the errorStream channel and tell the client
|
|
// that the error is fatal, the notifier won't communicate until a new
|
|
// subscribe
|
|
func (t *Notifier) FatalError(name string, err error) {
|
|
t.Lock()
|
|
defer t.Unlock()
|
|
|
|
t.errorStream <- ServerError{
|
|
Event: Event{
|
|
Type: name,
|
|
Status: Error,
|
|
},
|
|
ErrorEvent: ErrorEvent{
|
|
Level: FatalError,
|
|
Message: err.Error(),
|
|
},
|
|
}
|
|
t.subscribed = false
|
|
}
|