diff --git a/pkg/visor/config.go b/pkg/visor/config.go index 0affd8cb3f..a5392cdafa 100644 --- a/pkg/visor/config.go +++ b/pkg/visor/config.go @@ -137,13 +137,13 @@ func (c *Config) RoutingTable() (routing.Table, error) { } // AppsConfig decodes AppsConfig from a local json config file. -func (c *Config) AppsConfig() ([]AppConfig, error) { - apps := make([]AppConfig, 0) +func (c *Config) AppsConfig() (map[string]AppConfig, error) { + apps := make(map[string]AppConfig) for _, app := range c.Apps { if app.Version == "" { app.Version = c.Version } - apps = append(apps, app) + apps[app.App] = app } return apps, nil diff --git a/pkg/visor/config_test.go b/pkg/visor/config_test.go index 1c6345f446..ebef92594d 100644 --- a/pkg/visor/config_test.go +++ b/pkg/visor/config_test.go @@ -101,13 +101,13 @@ func TestAppsConfig(t *testing.T) { appsConf, err := conf.AppsConfig() require.NoError(t, err) - app1 := appsConf[0] + app1 := appsConf["foo"] assert.Equal(t, "foo", app1.App) assert.Equal(t, "1.1", app1.Version) assert.Equal(t, routing.Port(1), app1.Port) assert.False(t, app1.AutoStart) - app2 := appsConf[1] + app2 := appsConf["bar"] assert.Equal(t, "bar", app2.App) assert.Equal(t, "1.0", app2.Version) assert.Equal(t, routing.Port(2), app2.Port) diff --git a/pkg/visor/rpc_test.go b/pkg/visor/rpc_test.go index 0dc2d3dd27..58bc268f1b 100644 --- a/pkg/visor/rpc_test.go +++ b/pkg/visor/rpc_test.go @@ -59,10 +59,9 @@ func TestUptime(t *testing.T) { } func TestListApps(t *testing.T) { - apps := []AppConfig{ - {App: "foo", AutoStart: false, Port: 10}, - {App: "bar", AutoStart: true, Port: 11}, - } + apps := make(map[string]AppConfig) + apps["foo"] = AppConfig{App: "foo", AutoStart: false, Port: 10} + apps["bar"] = AppConfig{App: "bar", AutoStart: true, Port: 11} sApps := map[string]*appBind{ "bar": {}, @@ -94,7 +93,8 @@ func TestStartStopApp(t *testing.T) { require.NoError(t, os.RemoveAll("skychat")) }() - apps := []AppConfig{{App: "foo", Version: "1.0", AutoStart: false, Port: 10}} + apps := make(map[string]AppConfig) + apps["foo"] = AppConfig{App: "foo", Version: "1.0", AutoStart: false, Port: 10} node := &Node{router: router, exec: executer, appsConf: apps, startedApps: map[string]*appBind{}, logger: logging.MustGetLogger("test"), conf: &Config{}} node.conf.Node.StaticPubKey = pk pathutil.EnsureDir(node.dir()) @@ -161,10 +161,9 @@ These tests have been commented out for the following reasons: // _, err = tm2.SaveTransport(context.TODO(), pk1, snet.DmsgType) // require.NoError(t, err) // -// apps := []AppConfig{ -// {App: "foo", Version: "1.0", AutoStart: false, Port: 10}, -// {App: "bar", Version: "2.0", AutoStart: false, Port: 20}, -// } +// apps := make(map[string]AppConfig) +// apps["foo"] = AppConfig{App: "foo", Version: "1.0", AutoStart: false, Port: 10} +// apps["bar"] = AppConfig{App: "bar", Version: "2.0", AutoStart: false, Port: 20} // conf := &Config{} // conf.Node.StaticPubKey = pk1 // node := &Node{ @@ -284,10 +283,10 @@ These tests have been commented out for the following reasons: // assert.Equal(t, ErrUnknownApp, err) // // require.NoError(t, gateway.SetAutoStart(&in2, &struct{}{})) -// assert.True(t, node.appsConf[0].AutoStart) +// assert.True(t, node.appsConf["foo"].AutoStart) // // require.NoError(t, gateway.SetAutoStart(&in3, &struct{}{})) -// assert.False(t, node.appsConf[0].AutoStart) +// assert.False(t, node.appsConf["foo"].AutoStart) // // // Test with RPC Client // diff --git a/pkg/visor/visor.go b/pkg/visor/visor.go index 6ba80442d4..e2795f3acb 100644 --- a/pkg/visor/visor.go +++ b/pkg/visor/visor.go @@ -103,7 +103,7 @@ type Node struct { appsPath string localPath string - appsConf []AppConfig + appsConf map[string]AppConfig startedMu sync.RWMutex startedApps map[string]*appBind @@ -403,28 +403,25 @@ func (node *Node) Apps() []*AppState { // StartApp starts registered App. func (node *Node) StartApp(appName string) error { - for _, appC := range node.appsConf { - if appC.App != appName { - continue - } - - done := make(chan struct{}, 1) - var err error + appConf, ok := node.appsConf[appName] + if !ok { + return ErrUnknownApp + } - go func(appC AppConfig) { - if err = node.SpawnApp(&appC, done); err != nil { - done <- struct{}{} - node.logger.Warnf("Failed to start app %s: %s", appName, err) - } - }(appC) + done := make(chan struct{}, 1) + var err error - <-done - close(done) + go func(appConf AppConfig) { + if err = node.SpawnApp(&appConf, done); err != nil { + done <- struct{}{} + node.logger.Warnf("Failed to start app %s: %s", appName, err) + } + }(appConf) - return err - } + <-done + close(done) - return ErrUnknownApp + return err } // SpawnApp configures and starts new App. @@ -543,13 +540,14 @@ func (node *Node) StopApp(appName string) error { // SetAutoStart sets an app to auto start or not. func (node *Node) SetAutoStart(appName string, autoStart bool) error { - for i, ac := range node.appsConf { - if ac.App == appName { - node.appsConf[i].AutoStart = autoStart - return nil - } + appConf, ok := node.appsConf[appName] + if !ok { + return ErrUnknownApp } - return ErrUnknownApp + + appConf.AutoStart = autoStart + node.appsConf[appName] = appConf + return nil } func (node *Node) stopApp(app string, bind *appBind) (err error) { diff --git a/pkg/visor/visor_test.go b/pkg/visor/visor_test.go index acfb544b61..cfc295b814 100644 --- a/pkg/visor/visor_test.go +++ b/pkg/visor/visor_test.go @@ -79,16 +79,15 @@ func TestMain(m *testing.M) { func TestNodeStartClose(t *testing.T) { r := new(mockRouter) executer := &MockExecuter{} - conf := []AppConfig{ - {App: "skychat", Version: "1.0", AutoStart: true, Port: 1}, - {App: "foo", Version: "1.0", AutoStart: false}, - } + apps := map[string]AppConfig{} + apps["skychat"] = AppConfig{App: "skychat", Version: "1.0", AutoStart: true, Port: 1} + apps["foo"] = AppConfig{App: "foo", Version: "1.0", AutoStart: false} defer func() { require.NoError(t, os.RemoveAll("skychat")) }() - node := &Node{conf: &Config{}, router: r, exec: executer, appsConf: conf, + node := &Node{conf: &Config{}, router: r, exec: executer, appsConf: apps, startedApps: map[string]*appBind{}, logger: logging.MustGetLogger("test")} dmsgC := dmsg.NewClient(cipher.PubKey{}, cipher.SecKey{}, disc.NewMock()) @@ -129,7 +128,8 @@ func TestNodeSpawnApp(t *testing.T) { defer func() { require.NoError(t, os.RemoveAll("skychat")) }() - apps := []AppConfig{{App: "skychat", Version: "1.0", AutoStart: false, Port: 10, Args: []string{"foo"}}} + apps := make(map[string]AppConfig) + apps["skychat"] = AppConfig{App: "skychat", Version: "1.0", AutoStart: false, Port: 10, Args: []string{"foo"}} node := &Node{router: r, exec: executer, appsConf: apps, startedApps: map[string]*appBind{}, logger: logging.MustGetLogger("test"), conf: &Config{}} node.conf.Node.StaticPubKey = pk