init
This commit is contained in:
43
internal/events/bus.go
Normal file
43
internal/events/bus.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package events
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Bus struct {
|
||||
subscribers map[chan *Event]struct{}
|
||||
}
|
||||
|
||||
func NewBus() *Bus {
|
||||
return &Bus{
|
||||
subscribers: make(map[chan *Event]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bus) Subscribe(ctx context.Context) chan *Event {
|
||||
ch := make(chan *Event, 100)
|
||||
b.subscribers[ch] = struct{}{}
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
b.unsubscribe(ch)
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
func (b *Bus) Publish(event *Event) {
|
||||
for ch := range b.subscribers {
|
||||
select {
|
||||
case ch <- event:
|
||||
default:
|
||||
log.Printf("Event channel full, dropping event: %s", event.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bus) unsubscribe(ch chan *Event) {
|
||||
delete(b.subscribers, ch)
|
||||
}
|
||||
67
internal/events/event.go
Normal file
67
internal/events/event.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package events
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"deployment-manager/internal/model"
|
||||
)
|
||||
|
||||
type EventType string
|
||||
|
||||
const (
|
||||
EventTypeRepoCreated EventType = "repo_created"
|
||||
EventTypeRepoUpdated EventType = "repo_updated"
|
||||
EventTypeRepoDeleted EventType = "repo_deleted"
|
||||
EventTypeDeployStarted EventType = "deploy_started"
|
||||
EventTypeDeploySuccess EventType = "deploy_success"
|
||||
EventTypeDeployError EventType = "deploy_error"
|
||||
EventTypeLog EventType = "log"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
ID string `json:"id"`
|
||||
Type EventType `json:"type"`
|
||||
RepoID int64 `json:"repo_id"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
func NewEvent(eventType EventType, repoID int64, data map[string]interface{}) *Event {
|
||||
return &Event{
|
||||
ID: generateEventID(),
|
||||
Type: eventType,
|
||||
RepoID: repoID,
|
||||
Data: data,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewRepoEvent(repo *model.Repo, eventType EventType) *Event {
|
||||
return NewEvent(eventType, repo.ID, map[string]interface{}{
|
||||
"repo": repo,
|
||||
})
|
||||
}
|
||||
|
||||
func NewLogEvent(repoID int64, message string) *Event {
|
||||
return NewEvent(EventTypeLog, repoID, map[string]interface{}{
|
||||
"message": message,
|
||||
})
|
||||
}
|
||||
|
||||
func (e *Event) ToJSON() ([]byte, error) {
|
||||
return json.Marshal(e)
|
||||
}
|
||||
|
||||
func generateEventID() string {
|
||||
return time.Now().Format("20060102150405") + "-" + randomString(8)
|
||||
}
|
||||
|
||||
func randomString(n int) string {
|
||||
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = letters[i%len(letters)]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
Reference in New Issue
Block a user