Skip to content

Commit 8d5b1b4

Browse files
authored
chore: Move component registry so it can be reused (#3297)
* Move component registry to component package so it can be reused outside of runtime package * Rename interface
1 parent a0145f5 commit 8d5b1b4

File tree

7 files changed

+100
-106
lines changed

7 files changed

+100
-106
lines changed

internal/component/registry.go

+84
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,87 @@ func AllNames() []string {
242242
slices.Sort(keys)
243243
return keys
244244
}
245+
246+
// Registry is a collection of registered components.
247+
type Registry interface {
248+
// Get looks up a component by name. It returns an error if the component does not exist or its usage is restricted,
249+
// for example, because of the component's stability level.
250+
Get(name string) (Registration, error)
251+
}
252+
253+
type defaultRegistry struct {
254+
minStability featuregate.Stability
255+
community bool
256+
}
257+
258+
// NewDefaultRegistry creates a new [Registry] which gets
259+
// components registered to github.com/grafana/alloy/internal/component.
260+
func NewDefaultRegistry(minStability featuregate.Stability, enableCommunityComps bool) Registry {
261+
return defaultRegistry{
262+
minStability: minStability,
263+
community: enableCommunityComps,
264+
}
265+
}
266+
267+
// Get retrieves a component using [component.Get]. It returns an error if the component does not exist,
268+
// or if the component's stability is below the minimum required stability level.
269+
func (reg defaultRegistry) Get(name string) (Registration, error) {
270+
cr, exists := Get(name)
271+
if !exists {
272+
return Registration{}, fmt.Errorf("cannot find the definition of component name %q", name)
273+
}
274+
275+
if cr.Community {
276+
if !reg.community {
277+
return Registration{}, fmt.Errorf("the component %q is a community component. Use the --feature.community-components.enabled command-line flag to enable community components", name)
278+
}
279+
return cr, nil // community components are not affected by feature stability
280+
}
281+
282+
err := featuregate.CheckAllowed(cr.Stability, reg.minStability, fmt.Sprintf("component %q", name))
283+
if err != nil {
284+
return Registration{}, err
285+
}
286+
return cr, nil
287+
}
288+
289+
type registryMap struct {
290+
registrations map[string]Registration
291+
minStability featuregate.Stability
292+
community bool
293+
}
294+
295+
// NewRegistryMap creates a new [Registry] which uses a map to store components.
296+
// Currently, it is only used in tests.
297+
func NewRegistryMap(
298+
minStability featuregate.Stability,
299+
community bool,
300+
registrations map[string]Registration,
301+
) Registry {
302+
303+
return &registryMap{
304+
registrations: registrations,
305+
minStability: minStability,
306+
community: community,
307+
}
308+
}
309+
310+
// Get retrieves a component using [component.Get].
311+
func (m registryMap) Get(name string) (Registration, error) {
312+
reg, ok := m.registrations[name]
313+
if !ok {
314+
return Registration{}, fmt.Errorf("cannot find the definition of component name %q", name)
315+
}
316+
if reg.Community {
317+
if !m.community {
318+
return Registration{}, fmt.Errorf("the component %q is a community component. Use the --feature.community-components.enabled command-line flag to enable community components", name)
319+
}
320+
return reg, nil // community components are not affected by feature stability
321+
}
322+
323+
err := featuregate.CheckAllowed(reg.Stability, m.minStability, fmt.Sprintf("component %q", name))
324+
if err != nil {
325+
return Registration{}, err
326+
}
327+
return reg, nil
328+
}

internal/runtime/alloy.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import (
5454
"github.com/prometheus/client_golang/prometheus"
5555
"go.uber.org/atomic"
5656

57+
"github.com/grafana/alloy/internal/component"
5758
"github.com/grafana/alloy/internal/featuregate"
5859
"github.com/grafana/alloy/internal/runtime/internal/controller"
5960
"github.com/grafana/alloy/internal/runtime/internal/importsource"
@@ -147,9 +148,9 @@ func New(o Options) *Runtime {
147148
type controllerOptions struct {
148149
Options
149150

150-
ComponentRegistry controller.ComponentRegistry // Custom component registry used in tests.
151-
ModuleRegistry *moduleRegistry // Where to register created modules.
152-
IsModule bool // Whether this controller is for a module.
151+
ComponentRegistry component.Registry // Custom component registry used in tests.
152+
ModuleRegistry *moduleRegistry // Where to register created modules.
153+
IsModule bool // Whether this controller is for a module.
153154
// A worker pool to evaluate components asynchronously. A default one will be created if this is nil.
154155
WorkerPool worker.Pool
155156
}

internal/runtime/alloy_services_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/grafana/alloy/internal/component"
99
"github.com/grafana/alloy/internal/featuregate"
10-
"github.com/grafana/alloy/internal/runtime/internal/controller"
1110
"github.com/grafana/alloy/internal/runtime/internal/testcomponents"
1211
"github.com/grafana/alloy/internal/runtime/internal/testservices"
1312
"github.com/grafana/alloy/internal/service"
@@ -211,7 +210,7 @@ func TestComponents_Using_Services(t *testing.T) {
211210
},
212211
}
213212

214-
registry = controller.NewRegistryMap(
213+
registry = component.NewRegistryMap(
215214
featuregate.StabilityGenerallyAvailable,
216215
true,
217216
map[string]component.Registration{
@@ -274,7 +273,7 @@ func TestComponents_Using_Services_In_Modules(t *testing.T) {
274273
},
275274
}
276275

277-
registry = controller.NewRegistryMap(
276+
registry = component.NewRegistryMap(
278277
featuregate.StabilityGenerallyAvailable,
279278
true,
280279
map[string]component.Registration{

internal/runtime/internal/controller/component_node_manager.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"sync"
66

7+
"github.com/grafana/alloy/internal/component"
78
"github.com/grafana/alloy/syntax/ast"
89
)
910

@@ -12,15 +13,15 @@ import (
1213
type ComponentNodeManager struct {
1314
globals ComponentGlobals
1415
// builtinComponentReg returns information to build and run built-in components.
15-
builtinComponentReg ComponentRegistry
16+
builtinComponentReg component.Registry
1617

1718
mut sync.RWMutex
1819
// customComponentReg returns information to build and run custom components.
1920
customComponentReg *CustomComponentRegistry
2021
}
2122

2223
// NewComponentNodeManager creates a new ComponentNodeManager without custom component registry.
23-
func NewComponentNodeManager(globals ComponentGlobals, componentReg ComponentRegistry) *ComponentNodeManager {
24+
func NewComponentNodeManager(globals ComponentGlobals, componentReg component.Registry) *ComponentNodeManager {
2425
return &ComponentNodeManager{
2526
globals: globals,
2627
builtinComponentReg: componentReg,

internal/runtime/internal/controller/component_registry.go

-92
This file was deleted.

internal/runtime/internal/controller/loader.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"go.opentelemetry.io/otel/codes"
1919
"go.opentelemetry.io/otel/trace"
2020

21+
"github.com/grafana/alloy/internal/component"
2122
"github.com/grafana/alloy/internal/component/common/loki"
2223
"github.com/grafana/alloy/internal/component/otelcol"
2324
"github.com/grafana/alloy/internal/featuregate"
@@ -65,10 +66,10 @@ type LoaderOptions struct {
6566
// ComponentGlobals contains data to use when creating components.
6667
ComponentGlobals ComponentGlobals
6768

68-
Services []service.Service // Services to load into the DAG.
69-
Host service.Host // Service host (when running services).
70-
ComponentRegistry ComponentRegistry // Registry to search for components.
71-
WorkerPool worker.Pool // Worker pool to use for async tasks.
69+
Services []service.Service // Services to load into the DAG.
70+
Host service.Host // Service host (when running services).
71+
ComponentRegistry component.Registry // Registry to search for components.
72+
WorkerPool worker.Pool // Worker pool to use for async tasks.
7273
}
7374

7475
// NewLoader creates a new Loader. Components built by the Loader will be built
@@ -84,7 +85,7 @@ func NewLoader(opts LoaderOptions) *Loader {
8485
parent, id := splitPath(globals.ControllerID)
8586

8687
if reg == nil {
87-
reg = NewDefaultComponentRegistry(opts.ComponentGlobals.MinStability, opts.ComponentGlobals.EnableCommunityComps)
88+
reg = component.NewDefaultRegistry(opts.ComponentGlobals.MinStability, opts.ComponentGlobals.EnableCommunityComps)
8889
}
8990

9091
l := &Loader{

internal/runtime/module.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ type moduleControllerOptions struct {
214214
ID string
215215

216216
// ComponentRegistry is where controllers can look up components.
217-
ComponentRegistry controller.ComponentRegistry
217+
ComponentRegistry component.Registry
218218

219219
// ModuleRegistry is a shared registry of running modules from the same root
220220
// controller.

0 commit comments

Comments
 (0)