Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Darkren committed Oct 17, 2019
1 parent 608cc38 commit 8e096b0
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 249 deletions.
88 changes: 0 additions & 88 deletions pkg/app2/app.go

This file was deleted.

80 changes: 0 additions & 80 deletions pkg/app2/app_manager.go

This file was deleted.

4 changes: 2 additions & 2 deletions pkg/app2/config.go → pkg/app2/appserver/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package app2
package appserver

// Config defines configuration parameters for `App`.
// Config defines configuration parameters for `Proc`.
type Config struct {
Name string `json:"name"`
Version string `json:"version"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/app2/key.go → pkg/app2/appserver/key.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package app2
package appserver

import "github.com/skycoin/dmsg/cipher"

Expand Down
99 changes: 99 additions & 0 deletions pkg/app2/appserver/proc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package appserver

import (
"fmt"
"os/exec"
"path/filepath"

"github.com/skycoin/skycoin/src/util/logging"
)

// Proc is a wrapper for a skywire app. Encapsulates
// the running proccess itself and the RPC server for
// app/visor communication.
type Proc struct {
key Key
config Config
log *logging.Logger
rpcS *Server
cmd *exec.Cmd
}

// NewProc constructs `Proc`.
func NewProc(log *logging.Logger, c Config, args []string) (*Proc, error) {
key := GenerateAppKey()

binaryPath := getBinaryPath(c.BinaryDir, c.Name, c.Version)

const (
appKeyEnvFormat = "APP_KEY=%s"
sockFileEnvFormat = "SW_UNIX=%s"
)

env := make([]string, 0, 2)
env = append(env, fmt.Sprintf(appKeyEnvFormat, key))
env = append(env, fmt.Sprintf(sockFileEnvFormat, c.SockFile))

cmd := exec.Command(binaryPath, args...) // nolint:gosec

cmd.Env = env
cmd.Dir = c.WorkDir

rpcS, err := New(logging.MustGetLogger(fmt.Sprintf("app_rpc_server_%s", key)),
c.SockFile, key)
if err != nil {
return nil, err
}

return &Proc{
key: key,
config: c,
log: log,
cmd: cmd,
rpcS: rpcS,
}, nil
}

// Run runs the application. It starts the process and runs the
// RPC communication server.
func (p *Proc) Run() error {
go func() {
if err := p.rpcS.ListenAndServe(); err != nil {
p.log.WithError(err).Error("error serving RPC")
}
}()

if err := p.cmd.Run(); err != nil {
p.closeRPCServer()
return err
}

return nil
}

// Stop stops the applicacation. It stops the process and
// shuts down the RPC server.
func (p *Proc) Stop() error {
p.closeRPCServer()
return p.cmd.Process.Kill()
}

// Wait shuts down the RPC server and waits for the
// application cmd to exit.
func (p *Proc) Wait() error {
p.closeRPCServer()
return p.cmd.Wait()
}

// closeRPCServer closes RPC server and logs error if any.
func (p *Proc) closeRPCServer() {
if err := p.rpcS.Close(); err != nil {
p.log.WithError(err).Error("error closing RPC server")
}
}

// getBinaryPath formats binary path using app dir, name and version.
func getBinaryPath(dir, name, ver string) string {
const binaryNameFormat = "%s.v%s"
return filepath.Join(dir, fmt.Sprintf(binaryNameFormat, name, ver))
}
74 changes: 74 additions & 0 deletions pkg/app2/appserver/proc_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package appserver

import (
"sync"

"github.com/pkg/errors"

"github.com/skycoin/skycoin/src/util/logging"
)

// ProcManager allows to manage skywire applications.
type ProcManager struct {
procs map[string]*Proc
mx sync.RWMutex
}

// NewProcManager constructs `ProcManager`.
func NewProcManager() *ProcManager {
return &ProcManager{
procs: make(map[string]*Proc),
}
}

// Run runs the application according to its config and additional args.
func (m *ProcManager) Run(log *logging.Logger, c Config, args []string) error {
// TODO: pass another logging instance?
p, err := NewProc(log, c, args)
if err != nil {
return err
}

if err := p.Run(); err != nil {
return err
}

m.mx.Lock()
m.procs[c.Name] = p
m.mx.Unlock()

return nil
}

// Stop stops the application.
func (m *ProcManager) Stop(name string) error {
p, err := m.pop(name)
if err != nil {
return err
}

return p.Stop()
}

// Wait waits for the application to exit.
func (m *ProcManager) Wait(name string) error {
p, err := m.pop(name)
if err != nil {
return err
}

return p.Wait()
}

func (m *ProcManager) pop(name string) (*Proc, error) {
m.mx.Lock()
p, ok := m.procs[name]
if !ok {
m.mx.Unlock()
return nil, errors.New("no such app")
}
delete(m.procs, name)
m.mx.Unlock()

return p, nil
}
5 changes: 1 addition & 4 deletions pkg/app2/appserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (

"github.com/pkg/errors"
"github.com/skycoin/skycoin/src/util/logging"

"github.com/skycoin/skywire/pkg/app2"
)

// Server is a server for app/visor communication.
Expand All @@ -18,13 +16,12 @@ type Server struct {
lis net.Listener
sockFile string
rpcS *rpc.Server
apps map[app2.Key]*app2.App
done sync.WaitGroup
stopCh chan struct{}
}

// NewServer constructs server.
func New(log *logging.Logger, sockFile string, appKey app2.Key) (*Server, error) {
func New(log *logging.Logger, sockFile string, appKey Key) (*Server, error) {
rpcS := rpc.NewServer()
gateway := newRPCGateway(logging.MustGetLogger(fmt.Sprintf("rpc_server_%s", appKey)))
if err := rpcS.RegisterName(string(appKey), gateway); err != nil {
Expand Down
Loading

0 comments on commit 8e096b0

Please sign in to comment.