diff --git a/internal/component/pool.go b/internal/component/pool.go deleted file mode 100644 index 3456fb0..0000000 --- a/internal/component/pool.go +++ /dev/null @@ -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) -} diff --git a/internal/dis/component.go b/internal/dis/component.go index 73ebcd6..59b5743 100644 --- a/internal/dis/component.go +++ b/internal/dis/component.go @@ -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 diff --git a/internal/dis/distillery.go b/internal/dis/distillery.go index a8803cd..1deb89d 100644 --- a/internal/dis/distillery.go +++ b/internal/dis/distillery.go @@ -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], + } } diff --git a/internal/dis/pool.go b/internal/dis/pool.go deleted file mode 100644 index a46b20c..0000000 --- a/internal/dis/pool.go +++ /dev/null @@ -1 +0,0 @@ -package dis