flow improvements #52
@ -4,10 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/silas/dag"
|
"github.com/silas/dag"
|
||||||
|
"github.com/unistack-org/micro/v3/client"
|
||||||
|
"github.com/unistack-org/micro/v3/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
type microFlow struct {
|
type microFlow struct {
|
||||||
@ -87,33 +88,44 @@ func (w *microWorkflow) Execute(ctx context.Context, req interface{}, opts ...Ex
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if options.Reverse {
|
||||||
|
err = w.g.SortedReverseDepthFirstWalk([]dag.Vertex{root}, fn)
|
||||||
|
} else {
|
||||||
err = w.g.SortedDepthFirstWalk([]dag.Vertex{root}, fn)
|
err = w.g.SortedDepthFirstWalk([]dag.Vertex{root}, fn)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
cherr := make(chan error)
|
cherr := make(chan error, 1)
|
||||||
|
defer close(cherr)
|
||||||
|
|
||||||
select {
|
nctx, cancel := context.WithCancel(ctx)
|
||||||
case err = <-cherr:
|
defer cancel()
|
||||||
return "", err
|
nopts := make([]ExecuteOption, 0, len(opts)+5)
|
||||||
default:
|
nopts = append(nopts, ExecuteClient(w.opts.Client), ExecuteTracer(w.opts.Tracer), ExecuteLogger(w.opts.Logger), ExecuteMeter(w.opts.Meter), ExecuteStore(w.opts.Store))
|
||||||
|
|
||||||
|
go func() {
|
||||||
for idx := range steps {
|
for idx := range steps {
|
||||||
wg.Add(len(steps[idx]))
|
wg.Add(len(steps[idx]))
|
||||||
for nidx := range steps[idx] {
|
for nidx := range steps[idx] {
|
||||||
go func(step Step) {
|
go func(step Step) {
|
||||||
if err = step.Execute(ctx, req, opts...); err != nil {
|
defer wg.Done()
|
||||||
|
if err = step.Execute(nctx, req, nopts...); err != nil {
|
||||||
cherr <- err
|
cherr <- err
|
||||||
|
cancel()
|
||||||
}
|
}
|
||||||
wg.Done()
|
|
||||||
}(steps[idx][nidx])
|
}(steps[idx][nidx])
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
}
|
cherr <- nil
|
||||||
|
}()
|
||||||
|
|
||||||
return uid.String(), nil
|
err = <-cherr
|
||||||
|
|
||||||
|
return uid.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFlow(opts ...Option) Flow {
|
func NewFlow(opts ...Option) Flow {
|
||||||
@ -236,9 +248,17 @@ func (s *microCallStep) Hashcode() interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *microCallStep) Execute(ctx context.Context, req interface{}, opts ...ExecuteOption) error {
|
func (s *microCallStep) Execute(ctx context.Context, req interface{}, opts ...ExecuteOption) error {
|
||||||
fmt.Printf("execute %s with %#v\n", s.String(), req)
|
options := NewExecuteOptions(opts...)
|
||||||
time.Sleep(1 * time.Second)
|
if options.Client == nil {
|
||||||
return nil
|
return fmt.Errorf("client not set")
|
||||||
|
}
|
||||||
|
rsp := &codec.Frame{}
|
||||||
|
copts := []client.CallOption{client.WithRetries(0)}
|
||||||
|
if options.Timeout > 0 {
|
||||||
|
copts = append(copts, client.WithRequestTimeout(options.Timeout), client.WithDialTimeout(options.Timeout))
|
||||||
|
}
|
||||||
|
err := options.Client.Call(ctx, options.Client.NewRequest(s.service, s.method, req), rsp)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
type microPublishStep struct {
|
type microPublishStep struct {
|
||||||
|
@ -2,6 +2,7 @@ package flow
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"github.com/unistack-org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"github.com/unistack-org/micro/v3/logger"
|
||||||
@ -117,12 +118,66 @@ type ExecuteOptions struct {
|
|||||||
Meter meter.Meter
|
Meter meter.Meter
|
||||||
// Store used for intermediate results
|
// Store used for intermediate results
|
||||||
Store store.Store
|
Store store.Store
|
||||||
|
// Context can be used to abort execution or pass additional opts
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
// Start step
|
||||||
Start string
|
Start string
|
||||||
|
// Reverse execution
|
||||||
|
Reverse bool
|
||||||
|
// Timeout for execution
|
||||||
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExecuteOption func(*ExecuteOptions)
|
type ExecuteOption func(*ExecuteOptions)
|
||||||
|
|
||||||
|
func ExecuteClient(c client.Client) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Client = c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteTracer(t tracer.Tracer) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Tracer = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteLogger(l logger.Logger) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Logger = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteMeter(m meter.Meter) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Meter = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteStore(s store.Store) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Store = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteContext(ctx context.Context) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Context = ctx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteReverse(b bool) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Reverse = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteTimeout(td time.Duration) ExecuteOption {
|
||||||
|
return func(o *ExecuteOptions) {
|
||||||
|
o.Timeout = td
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
|
func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
|
||||||
options := ExecuteOptions{}
|
options := ExecuteOptions{}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
Loading…
Reference in New Issue
Block a user