fix persistence injection

This commit is contained in:
c9s 2022-03-14 21:21:04 +08:00
parent a6a4eb94f0
commit b1559bcbe3
4 changed files with 46 additions and 11 deletions

View File

@ -84,6 +84,8 @@ func parseStructAndInject(f interface{}, objects ...interface{}) error {
continue
}
fieldName := st.Field(i).Name
switch k := fv.Kind(); k {
case reflect.Ptr, reflect.Struct:
@ -99,12 +101,18 @@ func parseStructAndInject(f interface{}, objects ...interface{}) error {
return fmt.Errorf("field %v of %s can not be set to %s, make sure it is an exported field", fv, sv.Type(), ot)
}
if k == reflect.Ptr && ot.Kind() == reflect.Struct {
fv.Set(reflect.ValueOf(obj).Addr())
} else {
fv.Set(reflect.ValueOf(obj))
if k == reflect.Ptr && !fv.IsNil() {
logrus.Debugf("[injection] field %s is not nil, not injecting", fieldName)
continue
}
if k == reflect.Ptr && ot.Kind() == reflect.Struct {
logrus.Debugf("[injection] found ptr + struct, injecting field %s to %T", fieldName, obj)
fv.Set(reflect.ValueOf(obj).Addr())
} else {
logrus.Debugf("[injection] injecting field %s to %T", fieldName, obj)
fv.Set(reflect.ValueOf(obj))
}
}
}

View File

@ -3,8 +3,9 @@ package bbgo
import (
"fmt"
"github.com/c9s/bbgo/pkg/service"
log "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/service"
)
type PersistenceSelector struct {
@ -48,6 +49,8 @@ func (p *Persistence) Load(val interface{}, subIDs ...string) error {
return err
}
log.Debugf("using persistence store %T for loading", ps)
if p.PersistenceSelector.StoreID == "" {
p.PersistenceSelector.StoreID = "default"
}
@ -62,6 +65,8 @@ func (p *Persistence) Save(val interface{}, subIDs ...string) error {
return err
}
log.Debugf("using persistence store %T for storing", ps)
if p.PersistenceSelector.StoreID == "" {
p.PersistenceSelector.StoreID = "default"
}

View File

@ -219,7 +219,7 @@ func (trader *Trader) RunSingleExchangeStrategy(ctx context.Context, strategy Si
return errors.New("strategy object is not a struct")
}
if err := trader.injectCommonServices(strategy) ; err != nil {
if err := trader.injectCommonServices(strategy); err != nil {
return err
}
@ -337,7 +337,7 @@ func (trader *Trader) Run(ctx context.Context) error {
continue
}
if err := trader.injectCommonServices(strategy) ; err != nil {
if err := trader.injectCommonServices(strategy); err != nil {
return err
}
@ -361,6 +361,29 @@ func (trader *Trader) injectCommonServices(s interface{}) error {
Facade: persistenceFacade,
}
// a special injection for persistence selector:
// if user defined the selector, the facade pointer will be nil, hence we need to update the persistence facade pointer
sv := reflect.ValueOf(s).Elem()
if field, ok := hasField(sv, "Persistence"); ok {
// the selector is set, but we need to update the facade pointer
if !field.IsNil() {
elem := field.Elem()
if elem.Kind() != reflect.Struct {
return fmt.Errorf("field Persistence is not a struct element, %s given", field)
}
if err := injectField(elem, "Facade", persistenceFacade, true); err != nil {
return err
}
/*
if err := parseStructAndInject(field.Interface(), persistenceFacade); err != nil {
return err
}
*/
}
}
return parseStructAndInject(s,
&trader.Graceful,
&trader.logger,
@ -371,11 +394,10 @@ func (trader *Trader) injectCommonServices(s interface{}) error {
trader.environment.AccountService,
trader.environment,
persistence,
persistenceFacade,
persistenceFacade, // if the strategy use persistence facade separately
)
}
// ReportPnL configure and set the PnLReporter with the given notifier
func (trader *Trader) ReportPnL() *PnLReporterManager {
return NewPnLReporter(&trader.environment.Notifiability)

View File

@ -242,9 +242,9 @@ func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Valu
func (s *Strategy) SaveState() error {
if err := s.Persistence.Save(s.state, ID, s.Symbol, stateKey); err != nil {
return err
} else {
log.Infof("state is saved => %+v", s.state)
}
log.Infof("state is saved => %+v", s.state)
return nil
}