reorganise runtime
This commit is contained in:
5
runtime/local/process/options.go
Normal file
5
runtime/local/process/options.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package process
|
||||
|
||||
type Options struct{}
|
||||
|
||||
type Option func(o *Options)
|
100
runtime/local/process/os/os.go
Normal file
100
runtime/local/process/os/os.go
Normal file
@@ -0,0 +1,100 @@
|
||||
// +build !windows
|
||||
|
||||
// Package os runs processes locally
|
||||
package os
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/micro/go-micro/runtime/local/process"
|
||||
)
|
||||
|
||||
func (p *Process) Exec(exe *process.Executable) error {
|
||||
cmd := exec.Command(exe.Package.Path)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (p *Process) Fork(exe *process.Executable) (*process.PID, error) {
|
||||
// create command
|
||||
cmd := exec.Command(exe.Package.Path, exe.Args...)
|
||||
// set env vars
|
||||
cmd.Env = append(cmd.Env, exe.Env...)
|
||||
|
||||
// create process group
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
in, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
er, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// start the process
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &process.PID{
|
||||
ID: fmt.Sprintf("%d", cmd.Process.Pid),
|
||||
Input: in,
|
||||
Output: out,
|
||||
Error: er,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Process) Kill(pid *process.PID) error {
|
||||
id, err := strconv.Atoi(pid.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr, err := os.FindProcess(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// now kill it
|
||||
err = pr.Kill()
|
||||
|
||||
// kill the group
|
||||
if pgid, err := syscall.Getpgid(id); err == nil {
|
||||
syscall.Kill(-pgid, syscall.SIGKILL)
|
||||
}
|
||||
|
||||
// return the kill error
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Process) Wait(pid *process.PID) error {
|
||||
id, err := strconv.Atoi(pid.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr, err := os.FindProcess(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ps, err := pr.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ps.Success() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf(ps.String())
|
||||
}
|
89
runtime/local/process/os/os_windows.go
Normal file
89
runtime/local/process/os/os_windows.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// Package os runs processes locally
|
||||
package os
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
|
||||
"github.com/micro/go-micro/runtime/process"
|
||||
)
|
||||
|
||||
func (p *Process) Exec(exe *process.Executable) error {
|
||||
cmd := exec.Command(exe.Package.Path)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (p *Process) Fork(exe *process.Executable) (*process.PID, error) {
|
||||
// create command
|
||||
cmd := exec.Command(exe.Package.Path, exe.Args...)
|
||||
// set env vars
|
||||
cmd.Env = append(cmd.Env, exe.Env...)
|
||||
|
||||
in, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
er, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// start the process
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &process.PID{
|
||||
ID: fmt.Sprintf("%d", cmd.Process.Pid),
|
||||
Input: in,
|
||||
Output: out,
|
||||
Error: er,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Process) Kill(pid *process.PID) error {
|
||||
id, err := strconv.Atoi(pid.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr, err := os.FindProcess(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// now kill it
|
||||
err = pr.Kill()
|
||||
|
||||
// return the kill error
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Process) Wait(pid *process.PID) error {
|
||||
id, err := strconv.Atoi(pid.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr, err := os.FindProcess(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ps, err := pr.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ps.Success() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf(ps.String())
|
||||
}
|
12
runtime/local/process/os/process.go
Normal file
12
runtime/local/process/os/process.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Package os runs processes locally
|
||||
package os
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/runtime/local/process"
|
||||
)
|
||||
|
||||
type Process struct{}
|
||||
|
||||
func NewProcess(opts ...process.Option) process.Process {
|
||||
return &Process{}
|
||||
}
|
41
runtime/local/process/process.go
Normal file
41
runtime/local/process/process.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Package process executes a binary
|
||||
package process
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/micro/go-micro/runtime/local/build"
|
||||
)
|
||||
|
||||
// Process manages a running process
|
||||
type Process interface {
|
||||
// Executes a process to completion
|
||||
Exec(*Executable) error
|
||||
// Creates a new process
|
||||
Fork(*Executable) (*PID, error)
|
||||
// Kills the process
|
||||
Kill(*PID) error
|
||||
// Waits for a process to exit
|
||||
Wait(*PID) error
|
||||
}
|
||||
|
||||
type Executable struct {
|
||||
// Package containing executable
|
||||
Package *build.Package
|
||||
// The env variables
|
||||
Env []string
|
||||
// Args to pass
|
||||
Args []string
|
||||
}
|
||||
|
||||
// PID is the running process
|
||||
type PID struct {
|
||||
// ID of the process
|
||||
ID string
|
||||
// Stdin
|
||||
Input io.Writer
|
||||
// Stdout
|
||||
Output io.Reader
|
||||
// Stderr
|
||||
Error io.Reader
|
||||
}
|
Reference in New Issue
Block a user