fixed installer

This commit is contained in:
anthdm 2024-06-07 11:03:09 +02:00
parent 99cbc94b2c
commit 1b5fc6bda9
4 changed files with 92 additions and 31 deletions

View file

@ -2,6 +2,4 @@ package events
import "context" import "context"
func HandleFooEvent(ctx context.Context, event any) { func HandleFooEvent(ctx context.Context, event any) {}
}

View file

@ -7,36 +7,54 @@ import (
"time" "time"
) )
// HandlerFunc is the function being called when receiving an event.
type HandlerFunc func(context.Context, any)
// Emit and event to the given topic
func Emit(topic string, event any) {
stream.emit(topic, event)
}
// Subscribe a HandlerFunc to the given topic.
// A Subscription is being returned that can be used
// to unsubscribe from the topic.
func Subscribe(topic string, h HandlerFunc) Subscription {
return stream.subscribe(topic, h)
}
// Unsubscribe unsubribes the given Subscription from its topic.
func Unsubscribe(sub Subscription) {
stream.unsubscribe(sub)
}
// Stop stops the event stream, cleaning up its resources.
func Stop() {
stream.stop()
}
var stream *eventStream
type event struct { type event struct {
topic string topic string
message any message any
} }
type CreateUserEvent struct{}
func HandleCreateUserEvent(ctx context.Context, event CreateUserEvent) {}
// Handler is the function being called when receiving an event.
type Handler func(context.Context, any)
// Subscription represents a handler subscribed to a specific topic. // Subscription represents a handler subscribed to a specific topic.
type Subscription struct { type Subscription struct {
Topic string Topic string
CreatedAt int64 CreatedAt int64
Handler Handler Fn HandlerFunc
} }
// EventStream type eventStream struct {
type EventStream struct {
mu sync.RWMutex mu sync.RWMutex
subs map[string][]Subscription subs map[string][]Subscription
eventch chan event eventch chan event
quitch chan struct{} quitch chan struct{}
} }
// New return a new EventStream func newStream() *eventStream {
func New() *EventStream { e := &eventStream{
e := &EventStream{
subs: make(map[string][]Subscription), subs: make(map[string][]Subscription),
eventch: make(chan event, 128), eventch: make(chan event, 128),
quitch: make(chan struct{}), quitch: make(chan struct{}),
@ -45,7 +63,7 @@ func New() *EventStream {
return e return e
} }
func (e *EventStream) start() { func (e *eventStream) start() {
ctx := context.Background() ctx := context.Background()
for { for {
select { select {
@ -54,35 +72,32 @@ func (e *EventStream) start() {
case evt := <-e.eventch: case evt := <-e.eventch:
if handlers, ok := e.subs[evt.topic]; ok { if handlers, ok := e.subs[evt.topic]; ok {
for _, sub := range handlers { for _, sub := range handlers {
go sub.Handler(ctx, evt.message) go sub.Fn(ctx, evt.message)
} }
} }
} }
} }
} }
// Stop stops the EventStream func (e *eventStream) stop() {
func (e *EventStream) Stop() {
e.quitch <- struct{}{} e.quitch <- struct{}{}
} }
// Emit an event by specifying a topic and an arbitrary data type func (e *eventStream) emit(topic string, v any) {
func (e *EventStream) Emit(topic string, v any) {
e.eventch <- event{ e.eventch <- event{
topic: topic, topic: topic,
message: v, message: v,
} }
} }
// Subscribe subscribes a handler to the given topic func (e *eventStream) subscribe(topic string, h HandlerFunc) Subscription {
func (e *EventStream) Subscribe(topic string, h Handler) Subscription {
e.mu.RLock() e.mu.RLock()
defer e.mu.RUnlock() defer e.mu.RUnlock()
sub := Subscription{ sub := Subscription{
CreatedAt: time.Now().UnixNano(), CreatedAt: time.Now().UnixNano(),
Topic: topic, Topic: topic,
Handler: h, Fn: h,
} }
if _, ok := e.subs[topic]; !ok { if _, ok := e.subs[topic]; !ok {
@ -94,8 +109,7 @@ func (e *EventStream) Subscribe(topic string, h Handler) Subscription {
return sub return sub
} }
// Unsubscribe unsubscribes the given Subscription func (e *eventStream) unsubscribe(sub Subscription) {
func (e *EventStream) Unsubscribe(sub Subscription) {
e.mu.RLock() e.mu.RLock()
defer e.mu.RUnlock() defer e.mu.RUnlock()
@ -104,4 +118,11 @@ func (e *EventStream) Unsubscribe(sub Subscription) {
return sub.CreatedAt == e.CreatedAt return sub.CreatedAt == e.CreatedAt
}) })
} }
if len(e.subs[sub.Topic]) == 0 {
delete(e.subs, sub.Topic)
}
}
func init() {
stream = newStream()
} }

View file

@ -1,8 +1,36 @@
package event package event
import ( import (
"context"
"reflect"
"sync"
"testing" "testing"
) )
func TestEventStream(t *testing.T) { func TestEventSubscribeEmit(t *testing.T) {
var (
expect = 1
wg = sync.WaitGroup{}
)
wg.Add(1)
Subscribe("foo.bar", func(_ context.Context, event any) {
value, ok := event.(int)
if !ok {
t.Errorf("expected int got %v", reflect.TypeOf(event))
}
if value != 1 {
t.Errorf("expected %d got %d", expect, value)
}
wg.Done()
})
Emit("foo.bar", expect)
wg.Wait()
}
func TestUnsubscribe(t *testing.T) {
sub := Subscribe("foo.bar", func(_ context.Context, _ any) {})
Unsubscribe(sub)
if _, ok := stream.subs["foo.bar"]; ok {
t.Errorf("expected topic foo.bar to be deleted")
}
} }

View file

@ -31,16 +31,30 @@ func main() {
projectName := args[0] projectName := args[0]
clone := exec.Command("git clone " + reponame) // check if gothkit folder already exists, if so, delete
fi, err := os.Stat("gothkit")
if err != nil {
log.Fatal(err)
}
if fi.IsDir() {
fmt.Println("-- deleting gothkit folder cause its already present")
if err := os.RemoveAll("gothkit"); err != nil {
log.Fatal(err)
}
}
fmt.Println("-- cloning", reponame)
clone := exec.Command("git", "clone", reponame)
if err := clone.Run(); err != nil { if err := clone.Run(); err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println("-- rename bootstrap to", projectName)
if err := os.Rename(path.Join("gothkit", bootstrapFolderName), projectName); err != nil { if err := os.Rename(path.Join("gothkit", bootstrapFolderName), projectName); err != nil {
log.Fatal(err) log.Fatal(err)
} }
err := filepath.Walk(path.Join(projectName), func(fullPath string, info fs.FileInfo, err error) error { err = filepath.Walk(path.Join(projectName), func(fullPath string, info fs.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
@ -72,5 +86,5 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
fmt.Printf("project (%s) successfully installed!\n", projectName) fmt.Printf("-- project (%s) successfully installed!\n", projectName)
} }