Documentation
¶
Overview ¶
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the Actor model abstractions:
- IActorSystem: Actor runtime — create, dispatch, call Actors
- IActor: single Actor instance — send messages, query state
- IActorHandler: Actor lifecycle and message routing callbacks
- IActorChild: parent Actor's child management
- IEventData: typed event payload
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines application-level abstractions:
- INode: node identity and configuration
- IApplication: the application container — component registry, lifecycle, service accessors
- ProfileJSON: typed profile/config reader
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the cluster-related abstractions:
- IDiscovery: node discovery service (member lookup and change notification)
- ICluster: cross-node messaging (publish and request/response)
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the component system:
- IComponent: named pluggable unit with lifecycle hooks
- IComponentLifecycle: Set → Init → OnAfterInit (startup), OnBeforeStop → OnStop (shutdown)
- Component: embeddable base with no-op lifecycle stubs
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the network connector abstraction:
- IConnector: listen/accept connections and emit OnConnect callbacks
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the in-process message carrier and Actor path helpers:
- Message: pooled, reference-counted envelope for Actor dispatch
- ActorPath: parsed {NodeID, ActorID, ChildID} triplet
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the frontend network parser abstraction:
- INetParser: protocol codec + connector assembly + agent Actor loading
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines the serialization abstraction:
- ISerializer: pluggable codec for message encoding/decoding
Package cherryFacade defines the core interfaces for the Cherry framework.
This file defines session and user identity type aliases.
Index ¶
- func NewChildPath(nodeID, actorID, childID interface{}) string
- func NewPath(nodeID, actorID interface{}) string
- type ActorPath
- type Component
- type IActor
- type IActorChild
- type IActorHandler
- type IActorSystem
- type IApplication
- type ICluster
- type IClusterComponent
- type IComponent
- type IComponentLifecycle
- type IConnector
- type IDiscovery
- type IDiscoveryComponent
- type IEventData
- type IMember
- type INetParser
- type INode
- type ISerializer
- type InvokeFunc
- type MemberListener
- type Message
- type OnConnectFunc
- type ProfileJSON
- type SID
- type UID
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewChildPath ¶ added in v1.3.1
func NewChildPath(nodeID, actorID, childID interface{}) string
NewChildPath builds a dotted path string. If childID is empty, it returns "nodeID.actorID"; otherwise "nodeID.actorID.childID".
Types ¶
type ActorPath ¶ added in v1.3.0
func NewActorPath ¶ added in v1.3.0
NewActorPath creates an ActorPath from individual components. Pass empty string for childID when targeting a parent Actor.
func ToActorPath ¶ added in v1.3.0
ToActorPath parses a dotted path string into an ActorPath. Accepts "node.actor" (2-segment) or "node.actor.child" (3-segment) formats.
func (*ActorPath) IsChild ¶ added in v1.3.0
IsChild returns true if this path targets a child Actor.
type Component ¶
type Component struct {
// contains filtered or unexported fields
}
Component is an embeddable base that provides no-op lifecycle methods. Embed this in your component struct to satisfy IComponent without implementing every hook.
func (*Component) App ¶ added in v1.3.0
func (p *Component) App() IApplication
App returns the Application this component is registered with. Available after Set() is called during startup.
func (*Component) Init ¶
func (*Component) Init()
Init is called after Set(), before any other component is initialized. Override to allocate resources that other components may depend on.
func (*Component) Name ¶
Name returns the component's unique name. Override this to return a non-empty string; the base implementation returns "".
func (*Component) OnAfterInit ¶
func (*Component) OnAfterInit()
OnAfterInit is called after ALL components have been Init'd. Override to access other components via p.App().Find(...).
func (*Component) OnBeforeStop ¶
func (*Component) OnBeforeStop()
OnBeforeStop is called before shutdown begins. Override to close connections or flush pending writes.
func (*Component) OnStop ¶
func (*Component) OnStop()
OnStop is the final shutdown hook. Called after all components' OnBeforeStop have run. Override to release resources.
func (*Component) Set ¶ added in v1.3.0
func (p *Component) Set(app IApplication)
Set stores the Application reference. Called by the framework once before Init(), in registration order.
type IActor ¶ added in v1.3.0
type IActor interface {
App() IApplication // the owning Application
ActorID() string // unique ID within the node
Path() *ActorPath // parsed "nodeID.actorID" path
Call(targetPath, funcName string, arg any) int32 // async RPC to another Actor, returns cherryCode status code
CallWait(targetPath, funcName string, arg, reply any) int32 // sync RPC with reply, returns cherryCode status code
CallType(nodeType, actorID, funcName string, arg any) int32 // call a random Actor of the given node type, returns cherryCode status code
PostRemote(m *Message) // fire-and-forget to a remote Actor
PostLocal(m *Message) // fire-and-forget to a local Actor
LastAt() int64 // last activity timestamp in ms, updated on each message
Exit() // stop this Actor; cannot be restarted
}
IActor is a single Actor instance running on its own goroutine. All handlers registered in OnInit are invoked serially on that goroutine — no locks are needed for Actor-local state.
Actors are created via IActorSystem.CreateActor and live until Exit() is called or the Application shuts down.
type IActorChild ¶ added in v1.3.0
type IActorChild interface {
Create(id string, handler IActorHandler) (IActor, error) // create a child Actor on the parent's goroutine
Get(id string) (IActor, bool) // get a child by ID; nil, false if not found
Remove(id string) // remove and stop a child Actor
Each(fn func(i IActor)) // iterate all children (the callback must not mutate the child set)
Call(childID, funcName string, arg any) // call a handler on a child Actor, returns cherryCode status code
CallWait(childID, funcName string, arg, reply any) int32 // call a handler on a child and wait for reply, returns cherryCode status code
}
IActorChild is implemented by parent Actors that can spawn and manage children. Children share the parent's goroutine — all Call and CallWait invocations are serial, so child handlers never run concurrently with each other or with the parent.
type IActorHandler ¶ added in v1.3.0
type IActorHandler interface {
AliasID() string // the ID string this Actor is registered under
OnInit() // called once before the message loop starts; register handlers here
OnStop() // called once before the goroutine exits; release resources here
OnLocalReceived(m *Message) (bool, bool) // returns (handled, needRecycle) — handled=true means the message was processed; needRecycle=true means caller should Recycle the message
OnRemoteReceived(m *Message) (bool, bool) // returns (handled, needRecycle) — handled=true means the message was processed; needRecycle=true means caller should Recycle the message
OnFindChild(m *Message) (IActor, bool) // resolve a child Actor from the message's Target path; returns the child and true if found
}
IActorHandler defines the lifecycle and message routing callbacks that every Actor must implement. Pass an IActorHandler to IActorSystem.CreateActor to register a new Actor type.
Lifecycle order:
AliasID() → OnInit() → [message loop] → OnStop()
type IActorSystem ¶ added in v1.3.0
type IActorSystem interface {
GetIActor(id string) (IActor, bool) // lookup an Actor by ID; nil, false if not found
CreateActor(id string, handler IActorHandler) (IActor, error) // create and start a new Actor
PostRemote(m *Message) bool // fire-and-forget to a remote Actor; returns false if delivery rejected
PostLocal(m *Message) bool // fire-and-forget to a local Actor; returns false if Actor not found
PostEvent(data IEventData) // broadcast an event to all subscribers matching data.Name()
Call(source, target, funcName string, arg any) int32 // async RPC to target actor, returns cherryCode status code
CallWait(source, target, funcName string, arg, reply any) int32 // sync RPC to target actor with reply, returns cherryCode status code
CallType(nodeType, actorID, funcName string, arg any) int32 // call a random Actor of the given node type, returns cherryCode status code
SetLocalInvoke(invoke InvokeFunc) // set the low-level dispatch hook for local messages
SetRemoteInvoke(invoke InvokeFunc) // set the low-level dispatch hook for remote messages
SetCallTimeout(d time.Duration) // set RPC call timeout (default 3s)
SetArrivalTimeout(t int64) // set message arrival timeout in ms (default 100ms)
SetExecutionTimeout(t int64) // set handler execution timeout in ms (default 100ms)
}
IActorSystem is the Actor runtime used by application-level code. It provides Actor creation, fire-and-forget message posting (local/remote/event), and RPC-style Call/CallWait/CallType invocations.
The framework registers a single IActorSystem implementation automatically via the actor_component. Business code accesses it through IApplication.ActorSystem().
type IApplication ¶
type IApplication interface {
INode
Running() bool // whether the application is running
DieChan() chan bool // closed when application shuts down
IsFrontend() bool // whether this is a frontend node
Register(components ...IComponent) // register components (before startup)
Find(name string) IComponent // find a component by name
Remove(name string) IComponent // remove a component by name
All() []IComponent // list all registered components
OnShutdown(fn ...func()) // register shutdown hooks (called in registration order)
Startup() // start the application (blocks until shutdown)
Shutdown() // shut down the application
Serializer() ISerializer // message serializer
Discovery() IDiscovery // node discovery service
Cluster() ICluster // cluster messaging service
ActorSystem() IActorSystem // Actor system
}
type ICluster ¶ added in v1.3.0
type ICluster interface {
Mode() string // cluster transport mode (e.g. "nats")
// PublishLocal delivers a message to an actor on the local node.
// The message is NOT serialized — it is passed in-process.
PublishLocal(nodeID string, msg *Message) error
// PublishRemote delivers a message to an actor on a remote node.
// The message is serialized and sent over the cluster transport.
PublishRemote(nodeID string, msg *Message) error
// PublishRemoteType delivers a message to a random actor of the given node type.
// Useful for load-balanced fan-out across a pool of workers.
PublishRemoteType(nodeType string, msg *Message) error
// RequestRemote sends a message to a remote actor and blocks until a response
// is received or the optional timeout expires. Returns the response payload
// and an error code. If no timeout is specified, a default is used.
RequestRemote(nodeID string, msg *Message, timeout ...time.Duration) ([]byte, int32)
}
ICluster provides cross-node messaging for the Cherry Actor system.
"Local" operations target actors within the same application process, avoiding serialization overhead. "Remote" operations serialize the message and route it through the cluster transport (NATS or similar).
Publish methods are fire-and-forget. RequestRemote sends a message and waits for a response, returning the raw payload and an error code.
type IClusterComponent ¶ added in v1.5.0
type IClusterComponent interface {
IComponent
ICluster
}
IClusterComponent combines the component lifecycle with cluster messaging capabilities.
type IComponent ¶
type IComponent interface {
Name() string // unique name within the Application
App() IApplication // the owning Application
IComponentLifecycle
}
IComponent is a named, lifecycle-aware unit registered with the Application. Components are initialized in registration order and stopped in reverse order.
type IComponentLifecycle ¶ added in v1.3.0
type IComponentLifecycle interface {
Set(app IApplication) // receive the owning Application reference
Init() // initialise internal state
OnAfterInit() // called after ALL components have been Init'd
OnBeforeStop() // called before shutdown begins
OnStop() // release resources
}
IComponentLifecycle defines the startup and shutdown hooks for a component. Startup: Set(app) → Init() → OnAfterInit() Shutdown: OnBeforeStop() → OnStop()
type IConnector ¶
type IConnector interface {
IComponent
Start() // begin accepting connections
Stop() // stop the listener and drain pending connections
OnConnect(fn OnConnectFunc) // register a callback invoked for each new connection
}
IConnector manages a network listener, accepting connections on a specific address and protocol. It emits each new connection through OnConnect callbacks, which downstream parsers use to create sessions and agent Actors.
Typical implementations wrap a TCP or WebSocket listener and handle accept loops internally. Start/Stop are called by the framework during application startup/shutdown.
type IDiscovery ¶ added in v1.1.5
type IDiscovery interface {
Mode() string // discovery mode name (e.g. "default", "nats", "etcd")
Map() map[string]IMember // snapshot of all known members keyed by nodeID
ListByType(nodeType string, filterNodeID ...string) []IMember // members of a given node type, excluding filterNodeID
Random(nodeType string) (IMember, bool) // random member of the given node type; nil, false if none exist
GetMember(nodeID string) (member IMember, found bool) // lookup a member by nodeID; nil, false if not found
UpdateSetting(key, value string) // update a single setting on THIS node and sync to other nodes
UpdateSettings(settings map[string]string) // update multiple settings on THIS node and sync to other nodes
OnAddMember(listener MemberListener) // register callback invoked after a member is added
OnUpdateMember(listener MemberListener) // register callback invoked after a member is updated
OnRemoveMember(listener MemberListener) // register callback invoked after a member is removed
}
IDiscovery is the discovery service interface used by business-level code. It provides read access to cluster member information, the ability to update the current node's settings and sync them to other nodes, and notification callbacks for membership changes.
Custom backends can implement this interface directly, or embed ComponentDefault from net/discovery to reuse the member storage and listener notification logic.
type IDiscoveryComponent ¶ added in v1.5.0
type IDiscoveryComponent interface {
IComponent
IDiscovery
}
IDiscoveryComponent combines the component lifecycle with discovery capabilities. Register implementations via cherryDiscovery.Register() to make them available to the application builder.
type IEventData ¶ added in v1.3.0
type IEventData interface {
Name() string // event name used for subscription matching
UniqueID() int64 // unique ID for deduplication — two events with the same ID are the same occurrence
}
IEventData is a typed event payload posted via IActorSystem.PostEvent. Actors subscribe by event Name in OnInit via EventRegister.
Multiple PostEvent calls for the same event may arrive at a subscriber; UniqueID allows the subscriber to detect and skip duplicates.
type IMember ¶ added in v1.1.5
type IMember interface {
GetNodeID() string // unique node identifier
GetNodeType() string // node type (e.g. "game", "gate", "map")
GetAddress() string // RPC address for cross-node communication
GetSettings() map[string]string // arbitrary key-value metadata for this node
}
IMember represents a cluster member visible to business code. Implementations may carry additional internal fields (e.g. heartbeat timestamp, timeout configuration) that are not exposed through this interface.
type INetParser ¶ added in v1.3.0
type INetParser interface {
Load(application IApplication) // register protocol-specific agent Actors
AddConnector(connector IConnector) // attach a network connector to this parser
Connectors() []IConnector // return all attached connectors
}
INetParser assembles the frontend access layer for the Application. It provides protocol-specific decoding, creates agent Actors for each connected client, and manages the set of network connectors.
Typical implementations (pomelo, simple) load their protocol handlers during Load(), attach to connector callbacks, and bridge raw connections to the Actor system via sessions and agent Actors.
If the Application is configured with isFrontend == true, a parser must be set or startup panics.
type INode ¶
type INode interface {
NodeID() string // globally unique node ID
NodeType() string // node type (e.g. "game", "gate", "map")
Address() string // public listen address (for frontend nodes)
RpcAddress() string // RPC listen address (reserved)
Settings() ProfileJSON // node settings from profile
Enabled() bool // whether this node is enabled
}
INode represents a cluster node's identity and configuration.
type ISerializer ¶
type ISerializer interface {
Marshal(v interface{}) ([]byte, error) // encode a value into bytes
Unmarshal(data []byte, v interface{}) error // decode bytes into a value
Name() string // codec name (e.g. "json", "protobuf")
}
ISerializer is a pluggable codec for message encoding and decoding. It is used by the cluster, Actor system, and connectors to serialize messages for cross-process transfer and deserialize incoming payloads.
Multiple implementations may coexist (e.g. "json", "protobuf"); the Name() method identifies which codec is in use.
type InvokeFunc ¶ added in v1.3.0
type InvokeFunc func(app IApplication, fi *creflect.FuncInfo, m *Message)
InvokeFunc is the low-level dispatch hook called when a message arrives at an Actor. It receives the owning Application, the resolved function metadata (FuncInfo), and the message envelope.
The framework sets this via SetLocalInvoke / SetRemoteInvoke during startup. Custom implementations are rare — the default invoke resolves the handler, deserializes args, and calls the registered function.
type MemberListener ¶ added in v1.1.5
type MemberListener func(member IMember)
MemberListener is called after a member is added, updated, or removed from the local table. The listener receives the affected member as its argument.
type Message ¶ added in v1.3.0
type Message struct {
BuildTime int64 // message build time(ms)
Source string // source actor path
Target string // target actor path (node.actor or node.actor.child)
FuncName string // target function name
Args interface{} // payload: same-node=decoded object, cross-node=[]byte (pending decode)
// --- Local only (client->Actor, set by parser) ---
Session *cproto.Session // client session
// --- Remote only (Actor->Actor, set by System.Call/CallWait/CallType) ---
ReqID string // NATS request ID (cross-node request-reply)
Reply string // NATS reply subject (non-empty if from cross-node)
ChanResult chan interface{} // same-node CallWait sync channel
// contains filtered or unexported fields
}
Message is the in-process message carrier for the Actor system. For cross-process transfer, use Marshal/Unmarshal which internally uses ClusterPacket proto.
Field groups:
Common: BuildTime, Source, Target, FuncName, Args Local (client->Actor, set by parser): Session Remote (Actor->Actor, set by System.Call/CallWait/CallType): ReqID, Reply, ChanResult
func GetMessage ¶ added in v1.3.0
func GetMessage() *Message
GetMessage returns a pooled Message with BuildTime set to now. Caller must Recycle() when done (or the receiving Actor will do so).
func (*Message) AddRef ¶ added in v1.5.2
func (p *Message) AddRef()
AddRef increments the reference count. Each call to PostLocal/PostRemote adds a reference that will be released by the receiving actor's Recycle.
func (*Message) Clone ¶ added in v1.5.2
Clone creates a shallow copy for child Actor forwarding. Session, Args and ChanResult are intentionally shared.
func (*Message) Marshal ¶ added in v1.5.2
Marshal serializes Message for cross-process transfer via NATS. Internally uses ClusterPacket proto as the wire format.
func (*Message) Recycle ¶ added in v1.3.0
func (p *Message) Recycle()
Recycle decrements the reference count and returns the Message to the pool when it reaches zero. Each PostLocal/PostRemote increments refs; the receiving Actor calls Recycle after processing. If delivery fails, the caller must Recycle.
func (*Message) TargetPath ¶ added in v1.3.0
TargetPath lazily parses the Target field into an ActorPath. Result is cached across the message lifetime and cleared on Recycle.
type OnConnectFunc ¶ added in v1.3.0
OnConnectFunc is called when a new connection is established.
type ProfileJSON ¶ added in v1.3.0
type ProfileJSON interface {
jsoniter.Any
GetConfig(path ...any) ProfileJSON
GetString(path any, defaultVal ...string) string
GetBool(path any, defaultVal ...bool) bool
GetInt(path any, defaultVal ...int) int
GetInt32(path any, defaultVal ...int32) int32
GetInt64(path any, defaultVal ...int64) int64
GetUint(path any, defaultVal ...uint) uint
GetUint32(path any, defaultVal ...uint32) uint32
GetUint64(path any, defaultVal ...uint64) uint64
GetFloat32(path any, defaultVal ...float32) float32
GetFloat64(path any, defaultVal ...float64) float64
GetDuration(path any, defaultVal ...time.Duration) time.Duration
Unmarshal(ptrVal any) error
}
ProfileJSON is a typed profile/config reader backed by jsoniter.