From afcbd58e374a9409f2e52f60b2904aded54b34db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jochum?= Date: Mon, 24 Feb 2025 05:56:40 +0100 Subject: [PATCH 1/3] feat: Sync with README from org --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6f93d76..56ca84b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # ![go-orb Logo](docs/logo-header.png) [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Go.Dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/go-orb/go-orb?tab=doc) [![Go Report Card](https://goreportcard.com/badge/github.com/go-orb/go-orb)](https://goreportcard.com/report/github.com/go-orb/go-orb) [![Discord](https://dcbadge.vercel.app/api/server/sggGS389qb?style=flat-square&theme=default-inverted)](https://discord.gg/sggGS389qb) -Orb is a framework for distributed systems development, it can be seen as the successor of [go-micro.dev/v4](https://github.com/go-micro/go-micro). +Go Orb is a framework for distributed systems development, it can be seen as the successor of [go-micro.dev/v4](https://github.com/go-micro/go-micro). + +The core of go-orb has been completly refactored, to support the removal of reflect and intodruction of wire. + +## Overview + +Go Orb provides the core requirements for distributed systems development including RPC and Event driven communication. +The Go Orb philosophy is sane defaults with a pluggable architecture. We provide defaults to get you started quickly +but everything can be easily swapped out. ## Features @@ -42,7 +50,7 @@ we have been working hard on removing all usage of reflect. Orb allows you to listen on multiple port's with different protocols: gRPC, HTTP, HTTPS, DRPC, HTTP2, H2C, HTTP3. See the config system entry on howto configure it. -### Advanced [config system](config) +### Advanced [config system](https://github.com/go-orb/go-orb/tree/main/config) With orb you can configure your plugins with a config file or environment options. @@ -50,7 +58,7 @@ With orb you can configure your plugins with a config file or environment option service1: server: handlers: - - Streams + - UserInfo middlewares: - middleware-1 entrypoints: @@ -69,7 +77,7 @@ service1: service1: server: handlers: - - Streams + - UserInfo middlewares: - middleware-1 - middleware-2 @@ -87,6 +95,7 @@ service1: - ImOnlyOnGRPC middlewares: - ImAGRPCSpecificMiddlware + - name: http plugin: http insecure: true From 195aec2bc87b315b57f5b6e3d7482761ff8c5235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jochum?= Date: Mon, 24 Feb 2025 07:29:11 +0100 Subject: [PATCH 2/3] fix(README): typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 56ca84b..f4ed133 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Go Orb is a framework for distributed systems development, it can be seen as the successor of [go-micro.dev/v4](https://github.com/go-micro/go-micro). -The core of go-orb has been completly refactored, to support the removal of reflect and intodruction of wire. +The core of go-orb has been completely refactored, to support the removal of reflect and introduction of wire. ## Overview From 157fbcd96221ffe70b1577c6840f20e8c25cf48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jochum?= Date: Wed, 26 Feb 2025 14:37:57 +0100 Subject: [PATCH 3/3] feat(all): Auto register components to types.Components, this makes service code much easier. --- event/event.go | 13 +++++++- log/log.go | 3 ++ metrics/metrics.go | 13 +++++++- registry/registry.go | 13 +++++++- server/server.go | 6 ++++ types/component.go | 26 ++++++++++++++- util/container/prioritylist.go | 59 ++++++++++++++++++++++++++++++++++ util/container/sorted.go | 49 ---------------------------- 8 files changed, 129 insertions(+), 53 deletions(-) create mode 100644 util/container/prioritylist.go delete mode 100644 util/container/sorted.go diff --git a/event/event.go b/event/event.go index fafbfb9..a0783a7 100644 --- a/event/event.go +++ b/event/event.go @@ -191,5 +191,16 @@ func Provide( cLogger = cLogger.With(slog.String("component", ComponentType), slog.String("plugin", cfg.Plugin)) - return provider(name, configs, cLogger, opts...) + instance, err := provider(name, configs, cLogger, opts...) + if err != nil { + return nil, err + } + + // Register the event as a component. + err = types.RegisterComponent(instance, types.PriorityEvent) + if err != nil { + logger.Warn("while registering event as a component", "error", err) + } + + return instance, nil } diff --git a/log/log.go b/log/log.go index de107b0..d28fb53 100644 --- a/log/log.go +++ b/log/log.go @@ -126,6 +126,9 @@ func Provide( slog.SetDefault(logger.Logger) + // Register the logger as a component. + _ = types.RegisterComponent(logger, types.PriorityLogger) //nolint:errcheck + return logger, nil } diff --git a/metrics/metrics.go b/metrics/metrics.go index f1b1e02..79302a3 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -88,5 +88,16 @@ func Provide( cLogger = cLogger.With(slog.String("component", ComponentType), slog.String("plugin", cfg.Plugin)) - return provider(name, version, configs, cLogger, opts...) + instance, err := provider(name, version, configs, cLogger, opts...) + if err != nil { + return Type{}, err + } + + // Register metrics as a component. + err = types.RegisterComponent(&instance, types.PriorityMetrics) + if err != nil { + logger.Warn("while registering metrics as a component", "error", err) + } + + return instance, nil } diff --git a/registry/registry.go b/registry/registry.go index 9bcea2b..b40706d 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -127,5 +127,16 @@ func Provide( cLogger = cLogger.With(slog.String("component", ComponentType), slog.String("plugin", cfg.Plugin)) - return provider(name, version, configs, cLogger, opts...) + instance, err := provider(name, version, configs, cLogger, opts...) + if err != nil { + return Type{}, err + } + + // Register the registry as a component. + err = types.RegisterComponent(&instance, types.PriorityRegistry) + if err != nil { + logger.Warn("while registering registry as a component", "error", err) + } + + return instance, nil } diff --git a/server/server.go b/server/server.go index 6840df7..ac89aa7 100644 --- a/server/server.go +++ b/server/server.go @@ -128,6 +128,12 @@ func Provide( entrypoints: eps, } + // Register the server as a component. + err := types.RegisterComponent(&srv, types.PriorityServer) + if err != nil { + logger.Warn("while registering server as a component", "error", err) + } + return srv, nil } diff --git a/types/component.go b/types/component.go index 3966da0..b27fb4d 100644 --- a/types/component.go +++ b/types/component.go @@ -1,6 +1,20 @@ package types -import "context" +import ( + "context" + + "github.com/go-orb/go-orb/util/container" +) + +// Priority constants. +const ( + PriorityLogger = 1000 + PriorityMetrics = 1100 + PriorityRegistry = 1200 + PriorityEvent = 1300 + PriorityServer = 1400 + PriorityClient = 1500 +) // Component needs to be implemented by every component. type Component interface { @@ -17,3 +31,13 @@ type Component interface { // String returns the component plugin name. String() string } + +// Components is the container for client implementations. +// +//nolint:gochecknoglobals +var Components = container.NewPriorityList[Component]() + +// RegisterComponent adds a component to the container. +func RegisterComponent(component Component, priority int) error { + return Components.Add(component, priority) +} diff --git a/util/container/prioritylist.go b/util/container/prioritylist.go new file mode 100644 index 0000000..7f768b7 --- /dev/null +++ b/util/container/prioritylist.go @@ -0,0 +1,59 @@ +package container + +import ( + "iter" + "sort" +) + +// PriorityListElement needs to be implemented by every interface. +type PriorityListElement[T any] struct { + Item T + Priority int +} + +// NewPriorityList creates a new priority list of elements. +func NewPriorityList[T any]() *PriorityList[T] { + return &PriorityList[T]{ + elements: []PriorityListElement[T]{}, + } +} + +// PriorityList is a priority list of elements. +type PriorityList[T any] struct { + elements []PriorityListElement[T] +} + +// Add adds a new factory function to this container. +// It returns ErrExists if the plugin already exists. +func (c *PriorityList[T]) Add(element T, priority int) error { + item := PriorityListElement[T]{ + Item: element, + Priority: priority, + } + + c.elements = append(c.elements, item) + + return nil +} + +// Iterate creates a new iterator over the elements of the priority list. +// Requires Go 1.23 or later. +func (c *PriorityList[T]) Iterate(reversed bool) iter.Seq2[int, T] { + if reversed { + sort.SliceStable(c.elements, func(p, q int) bool { + return c.elements[p].Priority > c.elements[q].Priority + }) + } else { + sort.SliceStable(c.elements, func(p, q int) bool { + return c.elements[p].Priority < c.elements[q].Priority + }) + } + + return func(yield func(int, T) bool) { + for i := 0; i <= len(c.elements)-1; i++ { + if !yield(c.elements[i].Priority, c.elements[i].Item) { + return + } + } + } +} diff --git a/util/container/sorted.go b/util/container/sorted.go deleted file mode 100644 index 663c97e..0000000 --- a/util/container/sorted.go +++ /dev/null @@ -1,49 +0,0 @@ -package container - -import ( - "fmt" - "sort" -) - -// SortedElement needs to be implemented by every interface. -type SortedElement interface { - fmt.Stringer - - Priority() int -} - -// NewSorted creates a new container that holds elements of type T sorted. -// Adds are costly as it sorts on each add, calls to Sorted() are free. -func NewSorted[T SortedElement]() *Sorted[T] { - return &Sorted[T]{ - elements: []T{}, - } -} - -// Sorted is a sorted container. -type Sorted[T SortedElement] struct { - elements []T -} - -// Add adds a new factory function to this container. -// It returns ErrExists if the plugin already exists. -func (c *Sorted[T]) Add(element T) error { - for _, e := range c.elements { - if e.String() == element.String() { - return ErrExists - } - } - - c.elements = append(c.elements, element) - - sort.SliceStable(c.elements, func(p, q int) bool { - return c.elements[p].Priority() < c.elements[q].Priority() - }) - - return nil -} - -// Sorted returns the internal list. -func (c *Sorted[T]) Sorted() []T { - return c.elements -}