script: implementation of error insertion on return (#986)

* exchanges/account: shift credentials to account package and segregate funds to keys

* merge: fixes

* linter: fix

* Update exchanges/account/account.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits + protection for string panic

* glorious_suggestion: add method for matching keys

* linter: fix tests

* account: add protected method for credentials minimizing access, display full account details to rpc.

* linter: spelling kweeeeeeen

* accounts/portfolio: clean/check portfolio code and quickly check balances from change. Add protected method for future matching.

* accounts: theres no point in pointerising everything

* linter: ok pointerise this then...

* exchanges: fix regression add in little notes.

* glorious: nits

* Update exchanges/account/credentials.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/account/credentials_test.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/account/credentials_test.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits

* gloriously: fix glorious glorious test gloriously

* script: initial implementation of error insertion on return

* script: make script context aware(ish) and update error handle in examples

* script: add tests

* script: add syntax highlighting to readme

* Update gctscript/vm/vm.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/vm/vm.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/examples/exchange/account_info.gct

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/examples/exchange/cancel_order.gct

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/examples/verbose.gct

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct_test.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits

* rm: bros

* scripts: handle errors in examples when they are going to use the data after fetching

* linter: fix rides again

* SCOTT_SPELL_CHECK_LINTER: fix

* gctscript: fix tests

* glorious: niiiiiiiiiiiiits

* scriptmodules/gct: standardize runtime errors

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits/reverts

* go mod: tidy

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
This commit is contained in:
Ryan O'Hara-Reid
2022-08-17 14:18:53 +10:00
committed by GitHub
parent 68588560e3
commit e93ee83563
42 changed files with 1110 additions and 372 deletions

View File

@@ -52,10 +52,11 @@ func (g *GctScriptManager) ShutdownAll() (err error) {
}
var shutdownErrors []error
AllVMSync.Range(func(k, v interface{}) bool {
AllVMSync.Range(func(_, v interface{}) bool {
vm, ok := v.(*VM)
if !ok {
shutdownErrors = append(shutdownErrors, errors.New("unable to type assert VM"))
return true
}
errShutdown := vm.Shutdown()
if err != nil {
@@ -73,7 +74,7 @@ func (g *GctScriptManager) ShutdownAll() (err error) {
// RemoveVM remove VM from list
func (g *GctScriptManager) RemoveVM(id uuid.UUID) error {
if _, f := AllVMSync.Load(id); !f {
if _, ok := AllVMSync.Load(id); !ok {
return fmt.Errorf(ErrNoVMFound, id.String())
}

View File

@@ -33,17 +33,12 @@ func NewManager(config *Config) (*GctScriptManager, error) {
if config == nil {
return nil, errors.New("config must be provided for script manager")
}
return &GctScriptManager{
config: config,
}, nil
return &GctScriptManager{config: config}, nil
}
// IsRunning returns if gctscript manager subsystem is started
func (g *GctScriptManager) IsRunning() bool {
if g == nil {
return false
}
return atomic.LoadInt32(&g.started) == 1
return g != nil && atomic.LoadInt32(&g.started) == 1
}
// Start starts gctscript subsystem and creates shutdown channel
@@ -54,12 +49,6 @@ func (g *GctScriptManager) Start(wg *sync.WaitGroup) (err error) {
if !atomic.CompareAndSwapInt32(&g.started, 0, 1) {
return fmt.Errorf("%s %s", caseName, ErrScriptFailedValidation)
}
defer func() {
if err != nil {
atomic.CompareAndSwapInt32(&g.started, 1, 0)
}
}()
g.shutdown = make(chan struct{})
wg.Add(1)
go g.run(wg)
@@ -74,9 +63,7 @@ func (g *GctScriptManager) Stop() error {
if atomic.LoadInt32(&g.started) == 0 {
return fmt.Errorf("%s not running", caseName)
}
defer func() {
atomic.CompareAndSwapInt32(&g.started, 1, 0)
}()
defer atomic.CompareAndSwapInt32(&g.started, 1, 0)
if err := g.ShutdownAll(); err != nil {
return err
@@ -90,9 +77,7 @@ func (g *GctScriptManager) run(wg *sync.WaitGroup) {
SetDefaultScriptOutput()
g.autoLoad()
defer func() {
wg.Done()
}()
defer wg.Done()
<-g.shutdown
}

View File

@@ -16,6 +16,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/crypto"
scriptevent "github.com/thrasher-corp/gocryptotrader/database/repository/script"
"github.com/thrasher-corp/gocryptotrader/gctscript/modules/gct"
"github.com/thrasher-corp/gocryptotrader/gctscript/modules/loader"
"github.com/thrasher-corp/gocryptotrader/gctscript/wrappers/validator"
"github.com/thrasher-corp/gocryptotrader/log"
@@ -33,10 +34,7 @@ func (g *GctScriptManager) NewVM() *VM {
}
newUUID, err := uuid.NewV4()
if err != nil {
log.Error(log.GCTScriptMgr, Error{
Action: "New: UUID",
Cause: err,
})
log.Error(log.GCTScriptMgr, Error{Action: "New: UUID", Cause: err})
return nil
}
@@ -82,18 +80,19 @@ func (vm *VM) Load(file string) error {
code, err := os.ReadFile(file)
if err != nil {
return &Error{
Action: "Load: ReadFile",
Script: file,
Cause: err,
}
return &Error{Action: "Load: ReadFile", Script: file, Cause: err}
}
vm.File = file
vm.Path = filepath.Dir(file)
vm.Script = tengo.NewScript(code)
scriptctx := vm.ShortName() + "-" + vm.ID.String()
err = vm.Script.Add("ctx", scriptctx)
scriptCtx := &gct.Context{}
scriptCtx.Value = map[string]tengo.Object{
"script": &tengo.String{Value: vm.ShortName() + "-" + vm.ID.String()},
}
err = vm.Script.Add("ctx", scriptCtx)
if err != nil {
return err
}
@@ -113,9 +112,8 @@ func (vm *VM) Load(file string) error {
// Compile compiles to byte code loaded copy of vm script
func (vm *VM) Compile() (err error) {
vm.Compiled = new(tengo.Compiled)
vm.Compiled, err = vm.Script.Compile()
return
return err
}
// RunCtx runs compiled byte code with context.Context support.
@@ -133,13 +131,10 @@ func (vm *VM) RunCtx() (err error) {
err = vm.Compiled.RunContext(ctx)
if err != nil {
vm.event(StatusFailure, TypeExecute)
return Error{
Action: "RunCtx",
Cause: err,
}
return Error{Action: "RunCtx", Cause: err}
}
vm.event(StatusSuccess, TypeExecute)
return
return nil
}
// CompileAndRun Compile and Run script with support for task running
@@ -176,21 +171,18 @@ func (vm *VM) CompileAndRun() {
}
return
}
if vm.T < time.Nanosecond {
log.Error(log.GCTScriptMgr, "Repeat timer cannot be under 1 nano second")
err = vm.Shutdown()
if err != nil {
log.Errorln(log.GCTScriptMgr, err)
}
if vm.T > 0 {
vm.runner()
return
}
vm.runner()
} else {
err = vm.Shutdown()
if err != nil {
log.Error(log.GCTScriptMgr, err)
if vm.T < 0 {
log.Error(log.GCTScriptMgr, "Repeat timer cannot be under 1 nano second")
}
return
}
err = vm.Shutdown()
if err != nil {
log.Error(log.GCTScriptMgr, err)
}
}
@@ -247,24 +239,23 @@ func (vm *VM) event(status, executionType string) {
}
func (vm *VM) scriptData() ([]byte, error) {
buf := new(bytes.Buffer)
w := zip.NewWriter(buf)
f, err := w.Create(vm.ShortName())
if err != nil {
return []byte{}, err
}
contents, err := vm.read()
if err != nil {
return []byte{}, err
return nil, err
}
buf := new(bytes.Buffer)
w := zip.NewWriter(buf)
f, err := w.Create(vm.ShortName())
if err != nil {
return nil, err
}
_, err = f.Write(contents)
if err != nil {
return []byte{}, err
return nil, err
}
err = w.Close()
if err != nil {
return []byte{}, err
return nil, err
}
return buf.Bytes(), nil
}

View File

@@ -34,11 +34,7 @@ const (
type vmscount int32
var (
pool = &sync.Pool{
New: func() interface{} {
return new(tengo.Script)
},
}
pool = &sync.Pool{New: func() interface{} { return new(tengo.Script) }}
// AllVMSync stores all current Virtual Machine instances
AllVMSync = &sync.Map{}
// VMSCount running total count of Virtual Machines