From 73a6bc362a0c0d45749dbd82313df679b06e11e1 Mon Sep 17 00:00:00 2001 From: zhangliang Date: Wed, 22 Sep 2021 17:20:08 +0800 Subject: [PATCH] feat: support tearing tick --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/agent/node.go | 16 ++++------------ pkg/agent/robot.go | 4 ++-- pkg/agent/tick.go | 43 ++++++++++++++++++++++++++++++++++--------- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index a7e6272..fc7ee2a 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,6 @@ require ( ) replace ( - github.com/hasura/go-graphql-client => github.com/LilithGames/go-graphql-client v0.3.0 - github.com/magicsea/behavior3go => github.com/LilithGames/behavior3go v0.0.8 + github.com/hasura/go-graphql-client => github.com/LilithGames/go-graphql-client v1.0.1 + github.com/magicsea/behavior3go => github.com/LilithGames/behavior3go v1.0.1 ) diff --git a/go.sum b/go.sum index fde9db9..e700f6e 100644 --- a/go.sum +++ b/go.sum @@ -7,10 +7,10 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/LilithGames/behavior3go v0.0.8 h1:F63BH0YodDw02DVpDpDdZhR7G9CAYiB0o92kdi5Kgm4= -github.com/LilithGames/behavior3go v0.0.8/go.mod h1:bqTRjmUHkU8u5UmTRzPJWkZeGRj6AJaYBlXksX5lpBc= -github.com/LilithGames/go-graphql-client v0.3.0 h1:LiMRDmPeH9YNHFC07EvSksQ02BgX2snkIRUwA5W742Y= -github.com/LilithGames/go-graphql-client v0.3.0/go.mod h1:ovhXpnBL/+pYmmdYHndovgAc/wmhaXKvKwJETjtMomQ= +github.com/LilithGames/behavior3go v1.0.1 h1:NyepIxQuFWYduU54Lb4MLu8kBUjGoRS6jRuIp+UflLA= +github.com/LilithGames/behavior3go v1.0.1/go.mod h1:bqTRjmUHkU8u5UmTRzPJWkZeGRj6AJaYBlXksX5lpBc= +github.com/LilithGames/go-graphql-client v1.0.1 h1:rvSakNfV4gsutAskCcvLNndhe6Uc6r4AsPCbp7+6t74= +github.com/LilithGames/go-graphql-client v1.0.1/go.mod h1:ovhXpnBL/+pYmmdYHndovgAc/wmhaXKvKwJETjtMomQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= diff --git a/pkg/agent/node.go b/pkg/agent/node.go index d0e8abf..cbdc665 100644 --- a/pkg/agent/node.go +++ b/pkg/agent/node.go @@ -39,18 +39,10 @@ func (n *Action) OnTick(ticker core.Ticker) behavior3go.Status { outcome.Err = err.Error() } outcome.Name = name - if status == behavior3go.RUNNING { - outcome.Name = "polling_" + name - } - outcome.Consume = time.Since(start).Nanoseconds() - - beginKey := "begin:" + name - begin := tick.Blackboard().GetMem(beginKey) - if begin != nil && status != behavior3go.RUNNING { - outcome.Consume = time.Since(begin.(time.Time)).Nanoseconds() - } - if begin == nil && status == behavior3go.RUNNING { - tick.Blackboard().SetMem(beginKey, start) + if start.UnixNano() < tick.recvTime { + outcome.Consume = tick.sendTime - tick.recvTime + } else { + outcome.Consume = time.Since(start).Nanoseconds() } tick.actorCtx().Send(tick.stat(), &outcome) return n.currentStatus(tick.context(), status) diff --git a/pkg/agent/robot.go b/pkg/agent/robot.go index c29957b..41c13f2 100644 --- a/pkg/agent/robot.go +++ b/pkg/agent/robot.go @@ -59,14 +59,14 @@ func (r *robot) execute(rootCtx *actor.RootContext) { start := time.Now() outcome := transfer.Outcome{Name: "whole_process"} board := core.NewBlackboard() - tick := NewTicker() + tick := NewTick() tick.market = r.task.market tick.ctx = r.task.ctx tick.statPID = r.task.statPID tick.actorRootContext = rootCtx var status behavior3go.Status for { - status = r.task.tree.Tick(tick, nil, board) + status = r.task.tree.Tick(tick, board) if status != behavior3go.RUNNING { break } diff --git a/pkg/agent/tick.go b/pkg/agent/tick.go index 8ecc889..9ed1255 100644 --- a/pkg/agent/tick.go +++ b/pkg/agent/tick.go @@ -4,6 +4,7 @@ import ( "context" "github.com/AsynkronIT/protoactor-go/actor" "github.com/magicsea/behavior3go/core" + "strconv" "sync/atomic" "time" ) @@ -75,8 +76,8 @@ type Ticker interface { context() context.Context stat() *actor.PID actorCtx() *actor.RootContext - RecvTime(timestamp time.Duration) - SendTime(timestamp time.Duration) + RecvTime(timestamp int64) + SendTime(timestamp int64) } type Tick struct { @@ -85,16 +86,32 @@ type Tick struct { ctx context.Context actorRootContext *actor.RootContext statPID *actor.PID - recvTime time.Duration - sendTime time.Duration + recvTime int64 + sendTime int64 } -func NewTicker() *Tick { +func NewTick() *Tick { tick := &Tick{} tick.Initialize() return tick } +// 用于并行的情况,分裂解决并发问题,一个行为树协程上下文使用一个tick +func (t *Tick) Tear(ticker core.Ticker) { + tick := ticker.(*Tick) + tick.market = t.market + tick.ctx = t.ctx + tick.statPID = t.statPID + tick.actorRootContext = t.actorRootContext + t.Tick.Tear(&tick.Tick) +} + +func (t *Tick) TearTick() core.Ticker { + tick := NewTick() + t.Tear(tick) + return tick +} + func (t *Tick) Marget() *Market { return t.market } @@ -111,10 +128,18 @@ func (t *Tick) actorCtx() *actor.RootContext { return t.actorRootContext } -func (t *Tick) RecvTime(timestamp time.Duration) { - t.recvTime = timestamp +func (t *Tick) RecvTime(unixNano string) { + t.recvTime = strToInt64(unixNano) +} + +func (t *Tick) SendTime(unixNano string) { + t.sendTime = strToInt64(unixNano) } -func (t *Tick) SendTime(timestamp time.Duration) { - t.sendTime = timestamp +func strToInt64(s string) int64 { + v, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return 0 + } + return v } \ No newline at end of file