client io architecture
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"galaxy/connector"
|
||||
mc "galaxy/model/client"
|
||||
"plugin"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
)
|
||||
|
||||
type ClientInit func(connector.UIConnector, fyne.App, mc.Settings) (mc.Client, error)
|
||||
|
||||
type loader struct {
|
||||
conn connector.Connector
|
||||
cli mc.Client
|
||||
}
|
||||
|
||||
func NewLoader(app fyne.App, conn connector.Connector) (*loader, error) {
|
||||
app.Storage().List()
|
||||
settings := mc.Settings{}
|
||||
cli, err := loadClientPlugin(conn, app, settings, "./client.so", "NewClient")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := &loader{
|
||||
conn: conn,
|
||||
cli: cli,
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (l *loader) Run(ctx context.Context) error {
|
||||
final := make(chan struct{}, 1)
|
||||
go l.backgroundLoop(ctx, final)
|
||||
if err := l.cli.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
final <- struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *loader) backgroundLoop(ctx context.Context, final <-chan struct{}) {
|
||||
t := time.NewTicker(time.Second * 5)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
l.cli.Shutdown()
|
||||
return
|
||||
case <-final:
|
||||
return
|
||||
case <-t.C:
|
||||
isGood := l.conn.CheckConnection()
|
||||
l.cli.OnConnection(isGood)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loadClientPlugin loads a Client implementation from a shared object (.so) file at the specified path.
|
||||
// It calls the constructor function by name, passing the necessary dependencies, and returns the initialized Client.
|
||||
func loadClientPlugin(conn connector.UIConnector, app fyne.App, s mc.Settings, path, name string) (mc.Client, error) {
|
||||
if path == "" {
|
||||
return nil, errors.New("no plugin path given")
|
||||
}
|
||||
|
||||
plug, err := plugin.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open plugin %q: %w", path, err)
|
||||
}
|
||||
|
||||
sym, err := plug.Lookup(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lookup symbol %q: %w", name, err)
|
||||
}
|
||||
|
||||
initializerPtr, ok := sym.(*ClientInit)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T; want %T", sym, initializerPtr)
|
||||
}
|
||||
|
||||
return (*initializerPtr)(conn, app, s)
|
||||
}
|
||||
Reference in New Issue
Block a user