internal/component: Move pool around
This commit is contained in:
parent
f7c8a43844
commit
9443217441
4 changed files with 116 additions and 155 deletions
|
|
@ -1,64 +0,0 @@
|
|||
package component
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||
)
|
||||
|
||||
// Pool holds a pool of components.
|
||||
type Pool struct {
|
||||
pool lazy.Pool[Component, Still]
|
||||
poolInit sync.Once
|
||||
}
|
||||
|
||||
func (pool *Pool) init() {
|
||||
pool.poolInit.Do(func() {
|
||||
pool.pool.Init = Init
|
||||
})
|
||||
}
|
||||
|
||||
type PoolContext = *lazy.PoolContext[Component]
|
||||
type AllFunc = func(context PoolContext) []Component
|
||||
|
||||
func (pool *Pool) All(core Still, init func(context PoolContext) []Component) []Component {
|
||||
pool.init()
|
||||
return pool.pool.All(core, init)
|
||||
}
|
||||
|
||||
// Make creates or returns a cached component of the given Context.
|
||||
//
|
||||
// Components are initialized by first calling the init function.
|
||||
// Then all component-like fields of fields are filled with their appropriate components.
|
||||
//
|
||||
// A component-like field has one of the following types:
|
||||
//
|
||||
// - A pointer to a struct type that implements component
|
||||
// - A slice type of an interface type that implements component
|
||||
//
|
||||
// These fields are initialized in an undefined order during initialization.
|
||||
// The init function may not rely on these existing.
|
||||
// Furthermore, the init function may not cause other components to be initialized.
|
||||
//
|
||||
// The init function may be nil, indicating that no additional initialization is required.
|
||||
func Make[C Component](context PoolContext, core Still, init func(component C)) C {
|
||||
return lazy.Make(context, init)
|
||||
}
|
||||
|
||||
// ExportAll exports all components that are a C from the pool.
|
||||
//
|
||||
// All should be the function of the core that initializes all components.
|
||||
// All should only make calls to [InitComponent].
|
||||
func ExportAll[C Component](pool *Pool, core Still, All AllFunc) []C {
|
||||
pool.init()
|
||||
return lazy.ExportComponents[Component, Still, C](&pool.pool, core, All)
|
||||
}
|
||||
|
||||
// Export exports the first component that is a C from the pool.
|
||||
//
|
||||
// All should be the function of the core that initializes all components.
|
||||
// All should only make calls to [InitComponent].
|
||||
func Export[C Component](pool *Pool, core Still, All AllFunc) C {
|
||||
pool.init()
|
||||
return lazy.ExportComponent[Component, Still, C](&pool.pool, core, All)
|
||||
}
|
||||
|
|
@ -1,80 +1,67 @@
|
|||
package dis
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/exporter"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/exporter/logger"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/home"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/info"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/meta"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/resolver"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/sql"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/ssh"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/static"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/triplestore"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/web"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||
"github.com/tkw1536/goprogram/lib/collection"
|
||||
)
|
||||
|
||||
// register returns all components of the distillery
|
||||
func (dis *Distillery) register(context component.PoolContext) []component.Component {
|
||||
return collection.MapSlice([]initFunc{
|
||||
auto[*web.Web],
|
||||
//
|
||||
// ==== init ====
|
||||
//
|
||||
|
||||
auto[*ssh.SSH],
|
||||
|
||||
manual(func(ts *triplestore.Triplestore) {
|
||||
ts.BaseURL = "http://" + dis.Upstream.Triplestore
|
||||
ts.PollContext = dis.Context()
|
||||
ts.PollInterval = time.Second
|
||||
}),
|
||||
manual(func(sql *sql.SQL) {
|
||||
sql.ServerURL = dis.Upstream.SQL
|
||||
sql.PollContext = dis.Context()
|
||||
sql.PollInterval = time.Second
|
||||
}),
|
||||
|
||||
auto[*instances.Instances],
|
||||
auto[*meta.Meta],
|
||||
|
||||
// Snapshots
|
||||
auto[*exporter.Exporter],
|
||||
auto[*logger.Logger],
|
||||
auto[*exporter.Config],
|
||||
auto[*exporter.Bookkeeping],
|
||||
auto[*exporter.Filesystem],
|
||||
auto[*exporter.Pathbuilders],
|
||||
|
||||
// Control server
|
||||
auto[*control.Control],
|
||||
auto[*static.Static],
|
||||
manual(func(home *home.Home) {
|
||||
home.RefreshInterval = time.Minute
|
||||
}),
|
||||
manual(func(resolver *resolver.Resolver) {
|
||||
resolver.RefreshInterval = time.Minute
|
||||
}),
|
||||
auto[*info.Info],
|
||||
}, func(f initFunc) component.Component {
|
||||
return f(dis, context)
|
||||
func (dis *Distillery) init() {
|
||||
dis.poolInit.Do(func() {
|
||||
dis.pool.Init = component.Init
|
||||
})
|
||||
}
|
||||
|
||||
type initFunc = func(dis *Distillery, context component.PoolContext) component.Component
|
||||
//
|
||||
// ==== registration ====
|
||||
//
|
||||
|
||||
// manual initializes a component from the provided distillery.
|
||||
func manual[C component.Component](init func(component C)) initFunc {
|
||||
return func(dis *Distillery, context component.PoolContext) component.Component {
|
||||
return component.Make(context, dis.Still, init)
|
||||
return func(context ctx) component.Component {
|
||||
return lazy.Make(context, init)
|
||||
}
|
||||
}
|
||||
|
||||
// use is like r, but does not provided additional initialization
|
||||
func auto[C component.Component](dis *Distillery, context component.PoolContext) component.Component {
|
||||
return component.Make[C](context, dis.Still, nil)
|
||||
func auto[C component.Component](context ctx) component.Component {
|
||||
return lazy.Make[component.Component, C](context, nil)
|
||||
}
|
||||
|
||||
// register returns all components of the distillery
|
||||
func (dis *Distillery) register(context ctx) []component.Component {
|
||||
dis.poolInit.Do(func() {
|
||||
dis.pool.Init = component.Init
|
||||
})
|
||||
|
||||
return collection.MapSlice(
|
||||
dis.allComponents(),
|
||||
func(f initFunc) component.Component {
|
||||
return f(context)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// ctx is a context for component initialization
|
||||
type ctx = *lazy.PoolContext[component.Component]
|
||||
|
||||
//
|
||||
// ==== export ====
|
||||
//
|
||||
|
||||
// export is a convenience function to export a single component
|
||||
func export[C component.Component](dis *Distillery) C {
|
||||
dis.init()
|
||||
return lazy.ExportComponent[component.Component, component.Still, C](&dis.pool, dis.Still, dis.register)
|
||||
}
|
||||
|
||||
func exportAll[C component.Component](dis *Distillery) []C {
|
||||
dis.init()
|
||||
return lazy.ExportComponents[component.Component, component.Still, C](&dis.pool, dis.Still, dis.register)
|
||||
}
|
||||
|
||||
type initFunc = func(context ctx) component.Component
|
||||
|
|
|
|||
|
|
@ -3,15 +3,24 @@ package dis
|
|||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/control"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/exporter"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/exporter/logger"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/home"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/info"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/meta"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/resolver"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/sql"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/ssh"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/static"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/triplestore"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component/web"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||
)
|
||||
|
||||
// Distillery represents a WissKI Distillery
|
||||
|
|
@ -31,8 +40,9 @@ type Distillery struct {
|
|||
// But for now this will just hold upstream configuration.
|
||||
Upstream Upstream
|
||||
|
||||
// Pool holds all the components in this pool
|
||||
pool component.Pool
|
||||
// pool holds all components
|
||||
pool lazy.Pool[component.Component, component.Still]
|
||||
poolInit sync.Once
|
||||
}
|
||||
|
||||
// Upstream contains the configuration for accessing remote configuration.
|
||||
|
|
@ -50,51 +60,80 @@ func (dis *Distillery) Context() context.Context {
|
|||
// PUBLIC COMPONENT GETTERS
|
||||
//
|
||||
|
||||
// e is a convenience function to export a single component
|
||||
func e[C component.Component](dis *Distillery) C {
|
||||
return component.Export[C](
|
||||
&dis.pool,
|
||||
dis.Still,
|
||||
dis.register,
|
||||
)
|
||||
}
|
||||
|
||||
func ea[C component.Component](dis *Distillery) []C {
|
||||
return component.ExportAll[C](
|
||||
&dis.pool,
|
||||
dis.Still,
|
||||
dis.register,
|
||||
)
|
||||
}
|
||||
|
||||
func (dis *Distillery) Control() *control.Control {
|
||||
return e[*control.Control](dis)
|
||||
return export[*control.Control](dis)
|
||||
}
|
||||
func (dis *Distillery) Resolver() *resolver.Resolver {
|
||||
return e[*resolver.Resolver](dis)
|
||||
return export[*resolver.Resolver](dis)
|
||||
}
|
||||
func (dis *Distillery) SSH() *ssh.SSH {
|
||||
return e[*ssh.SSH](dis)
|
||||
return export[*ssh.SSH](dis)
|
||||
}
|
||||
func (dis *Distillery) SQL() *sql.SQL {
|
||||
return e[*sql.SQL](dis)
|
||||
return export[*sql.SQL](dis)
|
||||
}
|
||||
func (dis *Distillery) Triplestore() *triplestore.Triplestore {
|
||||
return e[*triplestore.Triplestore](dis)
|
||||
return export[*triplestore.Triplestore](dis)
|
||||
}
|
||||
func (dis *Distillery) Instances() *instances.Instances {
|
||||
return e[*instances.Instances](dis)
|
||||
return export[*instances.Instances](dis)
|
||||
}
|
||||
func (dis *Distillery) Exporter() *exporter.Exporter {
|
||||
return e[*exporter.Exporter](dis)
|
||||
return export[*exporter.Exporter](dis)
|
||||
}
|
||||
|
||||
func (dis *Distillery) Installable() []component.Installable {
|
||||
return ea[component.Installable](dis)
|
||||
return exportAll[component.Installable](dis)
|
||||
}
|
||||
func (dis *Distillery) Updatable() []component.Updatable {
|
||||
return ea[component.Updatable](dis)
|
||||
return exportAll[component.Updatable](dis)
|
||||
}
|
||||
func (dis *Distillery) Provisionable() []component.Provisionable {
|
||||
return ea[component.Provisionable](dis)
|
||||
return exportAll[component.Provisionable](dis)
|
||||
}
|
||||
|
||||
//
|
||||
// All components
|
||||
// THESE SHOULD NEVER BE CALLED DIRECTLY
|
||||
//
|
||||
|
||||
func (dis *Distillery) allComponents() []initFunc {
|
||||
return []initFunc{
|
||||
auto[*web.Web],
|
||||
|
||||
auto[*ssh.SSH],
|
||||
|
||||
manual(func(ts *triplestore.Triplestore) {
|
||||
ts.BaseURL = "http://" + dis.Upstream.Triplestore
|
||||
ts.PollContext = dis.Context()
|
||||
ts.PollInterval = time.Second
|
||||
}),
|
||||
manual(func(sql *sql.SQL) {
|
||||
sql.ServerURL = dis.Upstream.SQL
|
||||
sql.PollContext = dis.Context()
|
||||
sql.PollInterval = time.Second
|
||||
}),
|
||||
|
||||
auto[*instances.Instances],
|
||||
auto[*meta.Meta],
|
||||
|
||||
// Snapshots
|
||||
auto[*exporter.Exporter],
|
||||
auto[*logger.Logger],
|
||||
auto[*exporter.Config],
|
||||
auto[*exporter.Bookkeeping],
|
||||
auto[*exporter.Filesystem],
|
||||
auto[*exporter.Pathbuilders],
|
||||
|
||||
// Control server
|
||||
auto[*control.Control],
|
||||
auto[*static.Static],
|
||||
manual(func(home *home.Home) {
|
||||
home.RefreshInterval = time.Minute
|
||||
}),
|
||||
manual(func(resolver *resolver.Resolver) {
|
||||
resolver.RefreshInterval = time.Minute
|
||||
}),
|
||||
auto[*info.Info],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
package dis
|
||||
Loading…
Add table
Add a link
Reference in a new issue