diff --git a/bootstrap/app/handlers/auth.go b/bootstrap/app/handlers/auth.go index f54f5d4..dfe47e1 100644 --- a/bootstrap/app/handlers/auth.go +++ b/bootstrap/app/handlers/auth.go @@ -5,7 +5,7 @@ import ( "AABBCCDD/app/types" - "github.com/anthdm/gothkit/pkg/kit" + "github.com/anthdm/gothkit/kit" ) func HandleAuthentication(w http.ResponseWriter, r *http.Request) (kit.Auth, error) { diff --git a/bootstrap/app/handlers/landing.go b/bootstrap/app/handlers/landing.go index eff84b1..c5ea09d 100644 --- a/bootstrap/app/handlers/landing.go +++ b/bootstrap/app/handlers/landing.go @@ -1,13 +1,11 @@ package handlers import ( - "AABBCCDD/app/db" "AABBCCDD/app/views/landing" - "github.com/anthdm/gothkit/pkg/kit" + "github.com/anthdm/gothkit/kit" ) func HandleLandingIndex(kit *kit.Kit) error { - db.Query.NewSelect().Scan(kit.Request.Context()) return kit.Render(landing.Index()) } diff --git a/bootstrap/app/routes.go b/bootstrap/app/routes.go index 1f83161..06bfb0d 100644 --- a/bootstrap/app/routes.go +++ b/bootstrap/app/routes.go @@ -5,8 +5,8 @@ import ( "AABBCCDD/app/views/errors" "log/slog" - "github.com/anthdm/gothkit/pkg/kit" - "github.com/anthdm/gothkit/pkg/kit/middleware" + "github.com/anthdm/gothkit/kit" + "github.com/anthdm/gothkit/kit/middleware" "github.com/go-chi/chi/v5" chimiddleware "github.com/go-chi/chi/v5/middleware" diff --git a/bootstrap/app/views/landing/index.templ b/bootstrap/app/views/landing/index.templ index 94746be..7f2ba94 100644 --- a/bootstrap/app/views/landing/index.templ +++ b/bootstrap/app/views/landing/index.templ @@ -1,7 +1,7 @@ package landing import ( - "github.com/anthdm/gothkit/pkg/view" + "github.com/anthdm/gothkit/view" "AABBCCDD/app/views/layouts" ) diff --git a/bootstrap/cmd/app/main.go b/bootstrap/cmd/app/main.go index d03592d..71fabbb 100644 --- a/bootstrap/cmd/app/main.go +++ b/bootstrap/cmd/app/main.go @@ -6,7 +6,7 @@ import ( "net/http" "os" - "github.com/anthdm/gothkit/pkg/kit" + "github.com/anthdm/gothkit/kit" "github.com/go-chi/chi/v5" ) diff --git a/bootstrap/go.mod b/bootstrap/go.mod index 2a1df69..2446b7e 100644 --- a/bootstrap/go.mod +++ b/bootstrap/go.mod @@ -2,20 +2,18 @@ module AABBCCDD go 1.22.0 -require ( - github.com/anthdm/gothkit v0.0.0-00010101000000-000000000000 - github.com/go-chi/chi/v5 v5.0.12 -) +require github.com/go-chi/chi/v5 v5.0.12 require ( - github.com/fatih/color v1.16.0 // indirect + github.com/anthdm/gothkit v0.0.0-20240606095122-e65b6d50b1a7 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/sys v0.19.0 // indirect + golang.org/x/sys v0.21.0 // indirect ) require ( diff --git a/bootstrap/go.sum b/bootstrap/go.sum index d6e0145..bac3d5c 100644 --- a/bootstrap/go.sum +++ b/bootstrap/go.sum @@ -1,11 +1,12 @@ github.com/a-h/templ v0.2.707 h1:T1Gkd2ugbRglZ9rYw/VBchWOSZVKmetDbBkm4YubM7U= github.com/a-h/templ v0.2.707/go.mod h1:5cqsugkq9IerRNucNsI4DEamdHPsoGMQy99DzydLhM8= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/anthdm/gothkit v0.0.0-20240606095122-e65b6d50b1a7 h1:ziBhugyHw/CK0dpCvGD+98zKJ6P1SqwFoLKmLbOK7m0= +github.com/anthdm/gothkit v0.0.0-20240606095122-e65b6d50b1a7/go.mod h1:QLre7XyvsU9RKQKh0XFXUX+L5Lfph2jViZgtdfIDKsQ= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -29,5 +30,6 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/gothkit/pkg/db/db.go b/gothkit/db/db.go similarity index 100% rename from gothkit/pkg/db/db.go rename to gothkit/db/db.go diff --git a/gothkit/event/event.go b/gothkit/event/event.go new file mode 100644 index 0000000..992b745 --- /dev/null +++ b/gothkit/event/event.go @@ -0,0 +1,103 @@ +package event + +import ( + "context" + "slices" + "sync" + "time" +) + +type event struct { + topic string + message any +} + +// 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. +type Subscription struct { + Topic string + CreatedAt int64 + Handler Handler +} + +// EventStream +type EventStream struct { + mu sync.RWMutex + subs map[string][]Subscription + eventch chan event + quitch chan struct{} +} + +// New return a new EventStream +func New() *EventStream { + e := &EventStream{ + subs: make(map[string][]Subscription), + eventch: make(chan event, 128), + quitch: make(chan struct{}), + } + go e.start() + return e +} + +func (e *EventStream) start() { + ctx := context.Background() + for { + select { + case <-e.quitch: + return + case evt := <-e.eventch: + if handlers, ok := e.subs[evt.topic]; ok { + for _, sub := range handlers { + go sub.Handler(ctx, evt.message) + } + } + } + } +} + +// Stop stops the EventStream +func (e *EventStream) Stop() { + e.quitch <- struct{}{} +} + +// Emit an event by specifying a topic and an arbitrary data type +func (e *EventStream) Emit(topic string, v any) { + e.eventch <- event{ + topic: topic, + message: v, + } +} + +// Subscribe subscribes a handler to the given topic +func (e *EventStream) Subscribe(topic string, h Handler) Subscription { + e.mu.RLock() + defer e.mu.RUnlock() + + sub := Subscription{ + CreatedAt: time.Now().UnixNano(), + Topic: topic, + Handler: h, + } + + if _, ok := e.subs[topic]; !ok { + e.subs[topic] = []Subscription{} + } + + e.subs[topic] = append(e.subs[topic], sub) + + return sub +} + +// Unsubscribe unsubscribes the given Subscription +func (e *EventStream) Unsubscribe(sub Subscription) { + e.mu.RLock() + defer e.mu.RUnlock() + + if _, ok := e.subs[sub.Topic]; ok { + e.subs[sub.Topic] = slices.DeleteFunc(e.subs[sub.Topic], func(e Subscription) bool { + return sub.CreatedAt == e.CreatedAt + }) + } +} diff --git a/gothkit/event/event_test.go b/gothkit/event/event_test.go new file mode 100644 index 0000000..620748e --- /dev/null +++ b/gothkit/event/event_test.go @@ -0,0 +1,8 @@ +package event + +import ( + "testing" +) + +func TestEventStream(t *testing.T) { +} diff --git a/gothkit/pkg/kit/kit.go b/gothkit/kit/kit.go similarity index 100% rename from gothkit/pkg/kit/kit.go rename to gothkit/kit/kit.go diff --git a/gothkit/pkg/kit/middleware/middleware.go b/gothkit/kit/middleware/middleware.go similarity index 100% rename from gothkit/pkg/kit/middleware/middleware.go rename to gothkit/kit/middleware/middleware.go diff --git a/gothkit/pkg/validate/validate.go b/gothkit/validate/validate.go similarity index 100% rename from gothkit/pkg/validate/validate.go rename to gothkit/validate/validate.go diff --git a/gothkit/pkg/view/view.go b/gothkit/view/view.go similarity index 87% rename from gothkit/pkg/view/view.go rename to gothkit/view/view.go index 811fba1..518efd2 100644 --- a/gothkit/pkg/view/view.go +++ b/gothkit/view/view.go @@ -4,8 +4,8 @@ import ( "context" "net/url" - "github.com/anthdm/gothkit/pkg/kit" - "github.com/anthdm/gothkit/pkg/kit/middleware" + "github.com/anthdm/gothkit/kit" + "github.com/anthdm/gothkit/kit/middleware" ) // Auth is a view helper function that returns the currency Auth.