From a10a13280cd8efdb7888de0745ac8f6a0b2f15dc Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Thu, 6 Jun 2024 12:48:15 +0800 Subject: [PATCH] =?UTF-8?q?other:=20v2=20vivid=20=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E3=80=81=E9=82=AE=E7=AE=B1=E6=B1=A0=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E4=BA=86=E6=9C=AA=E9=87=8D=E7=BD=AE=E7=9A=84=E9=82=AE?= =?UTF-8?q?=E7=AE=B1=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- minotaur/application.go | 12 +++++++++++ minotaur/application_test.go | 25 +++++------------------ minotaur/transport/conn_actor.go | 4 ++-- minotaur/vivid/actor.go | 2 +- minotaur/vivid/actor_context.go | 8 ++++++++ minotaur/vivid/actor_core.go | 4 ++++ minotaur/vivid/actor_ofo.go | 26 ++++++++++++++++++++++++ minotaur/vivid/actor_owner.go | 10 +++++++++ minotaur/vivid/actor_system.go | 14 ++++++------- minotaur/vivid/internal_actor_context.go | 2 +- minotaur/vivid/mailbox_fifo.go | 1 - minotaur/vivid/mailbox_priority.go | 12 ++++++++++- minotaur/vivid/message_context.go | 13 +++++++++++- minotaur/vivid/vivid.go | 20 +++++++++--------- 14 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 minotaur/vivid/actor_ofo.go create mode 100644 minotaur/vivid/actor_owner.go diff --git a/minotaur/application.go b/minotaur/application.go index 6ce2c40b..33da7c14 100644 --- a/minotaur/application.go +++ b/minotaur/application.go @@ -37,6 +37,14 @@ type Application struct { server *transport.Server } +func (a *Application) GetSystem() *vivid.ActorSystem { + return a.actorSystem +} + +func (a *Application) GetContext() vivid.ActorContext { + return a.actorSystem.GetContext() +} + func (a *Application) Launch() { defer func(a *Application) { close(a.closed) @@ -69,3 +77,7 @@ func (a *Application) EventBus() *pulse.Pulse { func (a *Application) ActorSystem() *vivid.ActorSystem { return a.actorSystem } + +func (a *Application) ActorOf(ofo vivid.ActorOfO) vivid.ActorRef { + return a.actorSystem.ActorOf(ofo) +} diff --git a/minotaur/application_test.go b/minotaur/application_test.go index 00b768ad..cd24676a 100644 --- a/minotaur/application_test.go +++ b/minotaur/application_test.go @@ -15,32 +15,17 @@ type AccountManager struct { func (e *AccountManager) OnReceive(ctx vivid.MessageContext) { switch ctx.GetMessage().(type) { case vivid.OnPreStart: - ctx.BindBehavior(vivid.BehaviorOf[transport.ServerConnOpenedEvent](e.onConnOpened)) + ctx.BindBehavior(vivid.BehaviorOf(e.onConnOpened)) e.EventBus().Subscribe("conn-opened", ctx, transport.ServerConnOpenedEvent{}) } } func (e *AccountManager) onConnOpened(ctx vivid.MessageContext, message transport.ServerConnOpenedEvent) { - vivid.ActorOf[*Account](e.ActorSystem(), vivid.NewActorOptions[*Account]().WithInit(func(account *Account) { - account.ConnActor = message.ConnActor + e.ActorSystem().ActorOf(vivid.OfO(func(actorOptions *vivid.ActorOptions[*Account]) { + actorOptions.WithInit(func(account *Account) { + account.ConnActor = message.ConnActor + }) })) - - vivid.ActorOfF[*Account](e.ActorSystem(), func(options *vivid.ActorOptions[*Account]) { - options. - WithName("account"). - WithInit(func(account *Account) { - account.ConnActor = message.ConnActor - }) - }) - - vivid.ActorOfI(e.ActorSystem(), new(Account), func(options *vivid.ActorOptions[*Account]) { - options. - WithName("account"). - WithInit(func(account *Account) { - account.ConnActor = message.ConnActor - }) - }) - } type Account struct { diff --git a/minotaur/transport/conn_actor.go b/minotaur/transport/conn_actor.go index b53b16a3..eed03c78 100644 --- a/minotaur/transport/conn_actor.go +++ b/minotaur/transport/conn_actor.go @@ -60,14 +60,14 @@ func (c *ConnActor) OnReceive(ctx vivid.MessageContext) { func (c *ConnActor) Write(packet Packet) { if c.writer == nil { - return + panic("should not happen, writer is nil") } c.writer.Tell(connWriteMessage{packet}) } func (c *ConnActor) React(packet Packet) { if c.reader == nil { - return + panic("should not happen, reader is nil") } c.reader.Tell(ConnReceivePacketMessage{packet}) } diff --git a/minotaur/vivid/actor.go b/minotaur/vivid/actor.go index eb327431..6d4ed202 100644 --- a/minotaur/vivid/actor.go +++ b/minotaur/vivid/actor.go @@ -17,7 +17,7 @@ func (i *FreeActor[T]) GetActor() T { } func onReceive(actor Actor, ctx MessageContext) { - actorCtx := ctx.getContext() + actorCtx, _ := ctx.GetContext().(*_ActorCore) if actorCtx == nil { actor.OnReceive(ctx) return diff --git a/minotaur/vivid/actor_context.go b/minotaur/vivid/actor_context.go index 74721886..1e620944 100644 --- a/minotaur/vivid/actor_context.go +++ b/minotaur/vivid/actor_context.go @@ -28,6 +28,10 @@ type ActorContext interface { // UnbindBehavior 解绑一个已绑定的行为 UnbindBehavior(message Message) + + // ActorOf 创建一个 Actor 并返回 ActorRef + // - ActorOfO 对象可通过 OfO 函数快速创建 + ActorOf(ofo ActorOfO) ActorRef } type _ActorContext struct { @@ -67,3 +71,7 @@ func (c *_ActorContext) UnbindBehavior(message Message) { delete(c.behaviors, reflect.TypeOf(message)) } + +func (c *_ActorContext) ActorOf(ofo ActorOfO) ActorRef { + return ofo.generate(c) +} diff --git a/minotaur/vivid/actor_core.go b/minotaur/vivid/actor_core.go index 1d042c5f..003b3224 100644 --- a/minotaur/vivid/actor_core.go +++ b/minotaur/vivid/actor_core.go @@ -63,6 +63,10 @@ type _ActorCore struct { messageHook func(MessageContext) bool // 消息钩子 } +func (a *_ActorCore) GetContext() ActorContext { + return a._ActorContext +} + func (a *_ActorCore) GetMailboxFactory() MailboxFactory { return a.mailboxFactory } diff --git a/minotaur/vivid/actor_ofo.go b/minotaur/vivid/actor_ofo.go new file mode 100644 index 00000000..aa523bdc --- /dev/null +++ b/minotaur/vivid/actor_ofo.go @@ -0,0 +1,26 @@ +package vivid + +// ActorOfO 该接口用于根据 ActorOptions 创建 Actor 并返回 ActorRef +// - 接口用于内部实现,外部无法直接实现 +type ActorOfO interface { + generate(of ActorOwner) ActorRef +} + +type actorOfO[T Actor] struct { + options []func(actorOptions *ActorOptions[T]) +} + +func (o *actorOfO[T]) generate(of ActorOwner) ActorRef { + var opts = new(ActorOptions[T]) + for _, opt := range o.options { + opt(opts) + } + return ActorOf(of, opts) +} + +// OfO 创建一个 ActorOfO 对象 +func OfO[T Actor](options ...func(actorOptions *ActorOptions[T])) ActorOfO { + return &actorOfO[T]{ + options: options, + } +} diff --git a/minotaur/vivid/actor_owner.go b/minotaur/vivid/actor_owner.go new file mode 100644 index 00000000..e077ccb0 --- /dev/null +++ b/minotaur/vivid/actor_owner.go @@ -0,0 +1,10 @@ +package vivid + +// ActorOwner 提供了作为合格 Actor 所有者的接口定义 +type ActorOwner interface { + // GetSystem 获取 Actor 所属的 ActorSystem + GetSystem() *ActorSystem + + // GetContext 获取 Actor 上下文 + GetContext() ActorContext +} diff --git a/minotaur/vivid/actor_system.go b/minotaur/vivid/actor_system.go index 5ca743e1..014e0c07 100644 --- a/minotaur/vivid/actor_system.go +++ b/minotaur/vivid/actor_system.go @@ -70,6 +70,10 @@ type ActorSystem struct { cluster string // 集群名称 } +func (s *ActorSystem) ActorOf(ofo ActorOfO) ActorRef { + return s.userGuard.ActorOf(ofo) +} + func (s *ActorSystem) Context() context.Context { return s.ctx } @@ -80,7 +84,7 @@ func (s *ActorSystem) Shutdown() { s.waitGroup.Wait() } -func (s *ActorSystem) getSystem() *ActorSystem { +func (s *ActorSystem) GetSystem() *ActorSystem { return s } @@ -88,12 +92,6 @@ func (s *ActorSystem) GetDeadLetters() DeadLetterStream { return s.deadLetters } -type actorOf interface { - getSystem() *ActorSystem - - getContext() *_ActorCore -} - func (s *ActorSystem) BindMailboxFactory(f MailboxFactory) MailboxFactoryId { s.mailboxFactorRW.Lock() defer s.mailboxFactorRW.Unlock() @@ -178,7 +176,7 @@ func (s *ActorSystem) getActor(id ActorId) *_ActorCore { return s.actors[id] } -func (s *ActorSystem) getContext() *_ActorCore { +func (s *ActorSystem) GetContext() ActorContext { return s.userGuard } diff --git a/minotaur/vivid/internal_actor_context.go b/minotaur/vivid/internal_actor_context.go index 46e748d7..cc0d024e 100644 --- a/minotaur/vivid/internal_actor_context.go +++ b/minotaur/vivid/internal_actor_context.go @@ -6,7 +6,7 @@ import ( ) type internalActorContext interface { - actorOf + ActorOwner // getLock 获取当前 ActorContext 的锁 // - 所有函数均不操作锁,应由外部调用者自行操作 diff --git a/minotaur/vivid/mailbox_fifo.go b/minotaur/vivid/mailbox_fifo.go index dd7850bf..c5e7433f 100644 --- a/minotaur/vivid/mailbox_fifo.go +++ b/minotaur/vivid/mailbox_fifo.go @@ -125,7 +125,6 @@ func (f *FIFO) reset() { f.Stop() } else { f.cond.L.Unlock() - return } f.cond.L.Lock() diff --git a/minotaur/vivid/mailbox_priority.go b/minotaur/vivid/mailbox_priority.go index e3747f82..da656982 100644 --- a/minotaur/vivid/mailbox_priority.go +++ b/minotaur/vivid/mailbox_priority.go @@ -113,6 +113,16 @@ func (p *Priority) GetLockable() sync.Locker { func (p *Priority) reset() { p.cond.L.Lock() + if p.status < fifoStateStopping { + p.cond.L.Unlock() + p.Stop() + } else { + p.cond.L.Unlock() + } + + p.cond.L.Lock() + defer p.cond.L.Unlock() + + p.status = priorityStateNone p.buffer = p.buffer[:0] - p.cond.L.Unlock() } diff --git a/minotaur/vivid/message_context.go b/minotaur/vivid/message_context.go index 27f9746a..1db096c6 100644 --- a/minotaur/vivid/message_context.go +++ b/minotaur/vivid/message_context.go @@ -7,7 +7,7 @@ import ( type MessageContext interface { context.Context - actorOf + ActorOwner ActorRef // GetContext 获取 Actor 上下文 @@ -42,6 +42,9 @@ type MessageContext interface { // UnbindBehavior 该函数是 ActorContext.UnbindBehavior 的快捷方式 UnbindBehavior(message Message) + + // ActorOf 该函数是 ActorContext.ActorOf 的快捷方式 + ActorOf(ofo ActorOfO) ActorRef } func newMessageContext(system *ActorSystem, message Message, priority int64, instantly, hasReply bool) *_MessageContext { @@ -81,6 +84,10 @@ type _MessageContext struct { InstantlyExec bool // 是否立即执行 } +func (c *_MessageContext) GetSystem() *ActorSystem { + return c.system +} + func (c *_MessageContext) Id() ActorId { return c.GetRef().Id() } @@ -244,3 +251,7 @@ func (c *_MessageContext) BindBehavior(behavior Behavior) { func (c *_MessageContext) UnbindBehavior(message Message) { c.GetContext().UnbindBehavior(message) } + +func (c *_MessageContext) ActorOf(ofo ActorOfO) ActorRef { + return c.GetContext().ActorOf(ofo) +} diff --git a/minotaur/vivid/vivid.go b/minotaur/vivid/vivid.go index 7cd2bcc9..2a5d1bef 100644 --- a/minotaur/vivid/vivid.go +++ b/minotaur/vivid/vivid.go @@ -18,7 +18,7 @@ func BehaviorOf[T Message](handler func(ctx MessageContext, message T)) Behavior return adp } -func ActorOfI[T Actor](actorOf actorOf, actor T, options ...func(options *ActorOptions[T])) ActorRef { +func ActorOfI[T Actor](actorOf ActorOwner, actor T, options ...func(options *ActorOptions[T])) ActorRef { var opts = NewActorOptions[T]().WithConstruct(actor) for _, opt := range options { opt(opts) @@ -26,7 +26,7 @@ func ActorOfI[T Actor](actorOf actorOf, actor T, options ...func(options *ActorO return ActorOf(actorOf, opts) } -func ActorOfF[T Actor](actorOf actorOf, options ...func(options *ActorOptions[T])) ActorRef { +func ActorOfF[T Actor](actorOf ActorOwner, options ...func(options *ActorOptions[T])) ActorRef { var opts = NewActorOptions[T]() for _, opt := range options { opt(opts) @@ -34,20 +34,20 @@ func ActorOfF[T Actor](actorOf actorOf, options ...func(options *ActorOptions[T] return ActorOf(actorOf, opts) } -func ActorOf[T Actor](actorOf actorOf, options ...*ActorOptions[T]) ActorRef { +func ActorOf[T Actor](actorOf ActorOwner, options ...*ActorOptions[T]) ActorRef { var opts = parseActorOptions(options...) var ins = opts.Construct if reflect.ValueOf(ins).IsNil() { tof := reflect.TypeOf((*T)(nil)).Elem().Elem() ins = reflect.New(tof).Interface().(T) } - var system = actorOf.getSystem() + var system = actorOf.GetSystem() if opts.Parent == nil { - opts.Parent = actorOf.getContext() + opts.Parent = actorOf.GetContext() } - ctx, err := generateActor[T](actorOf.getSystem(), ins, opts) + ctx, err := generateActor[T](actorOf.GetSystem(), ins, opts) if err != nil { system.deadLetters.DeadLetter(NewDeadLetterEvent(DeadLetterEventTypeActorOf, DeadLetterEventActorOf{ Error: err, @@ -63,20 +63,20 @@ func ActorOf[T Actor](actorOf actorOf, options ...*ActorOptions[T]) ActorRef { return ctx } -func FreeActorOf[T any](actorOf actorOf, options ...*ActorOptions[*FreeActor[T]]) ActorRef { +func FreeActorOf[T any](actorOf ActorOwner, options ...*ActorOptions[*FreeActor[T]]) ActorRef { var opts = parseActorOptions(options...) var ins = opts.Construct.actor if reflect.ValueOf(ins).IsNil() { tof := reflect.TypeOf((*T)(nil)).Elem().Elem() ins = reflect.New(tof).Interface().(T) } - var system = actorOf.getSystem() + var system = actorOf.GetSystem() if opts.Parent == nil { - opts.Parent = actorOf.getContext() + opts.Parent = actorOf.GetContext() } - ctx, err := generateActor[*FreeActor[T]](actorOf.getSystem(), &FreeActor[T]{actor: ins}, opts) + ctx, err := generateActor[*FreeActor[T]](actorOf.GetSystem(), &FreeActor[T]{actor: ins}, opts) if err != nil { system.deadLetters.DeadLetter(NewDeadLetterEvent(DeadLetterEventTypeActorOf, DeadLetterEventActorOf{ Error: err,