Skip to content

Commit

Permalink
feat(extensions): implement extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
Th3Shadowbroker committed Feb 26, 2025
1 parent 4ac5a88 commit a68db11
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
36 changes: 36 additions & 0 deletions ext/extension.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ext

import (
"fmt"
"plugin"
)

type Extension interface {
Info() *Info
Configure()
Enable()
Disable()
}

type Info struct {
Name string
}

func open(extFile string) (Extension, error) {
pl, err := plugin.Open(extFile)
if err != nil {
return nil, err
}

sym, err := pl.Lookup("Extension")
if err != nil {
return nil, err
}

ex, ok := sym.(Extension)
if !ok {
return nil, fmt.Errorf("the 'Extension' variable in %s does not implement the Extension interface", extFile)
}

return ex, nil
}
9 changes: 9 additions & 0 deletions ext/lifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ext

const (
LifecycleConfigure = LifecyclePhase(0)
LifecycleEnable = LifecyclePhase(1)
LifecycleDisable = LifecyclePhase(2)
)

type LifecyclePhase int
78 changes: 78 additions & 0 deletions ext/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package ext

import (
"fmt"
"os"
"path/filepath"
"strings"
)

type Registry struct {
extensions map[string]Extension
}

func NewRegistry() *Registry {
return &Registry{
extensions: make(map[string]Extension),
}
}

func (r *Registry) RegisterDir(dir string) error {
entries, err := os.ReadDir(dir)
if err != nil {
return err
}

for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".so") {
continue
}

ext, err := open(filepath.Join(dir, entry.Name()))
if err != nil {
return err
}

if err := r.Register(ext); err != nil {
return err
}
}

return nil
}

func (r *Registry) Register(ext Extension) error {
extensionName := ext.Info().Name
if r.IsRegistered(ext) {
return fmt.Errorf("theres already an extension with the name '%s'", extensionName)
}

r.extensions[extensionName] = ext
return nil
}

func (r *Registry) IsRegistered(ext Extension) bool {
extensionName := ext.Info().Name
_, ok := r.extensions[extensionName]
return ok
}

func (r *Registry) RunLifecyclePhase(phase LifecyclePhase) {
for _, ext := range r.extensions {
switch phase {

case LifecycleConfigure:
ext.Configure()

case LifecycleEnable:
ext.Enable()

case LifecycleDisable:
ext.Disable()

default:
panic(fmt.Errorf("unknown lifecycle phase with id '%d'", int(phase)))

}
}
}

0 comments on commit a68db11

Please sign in to comment.