cherryFacade

package
v1.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 12 Imported by: 55

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

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".

func NewPath added in v1.3.0

func NewPath(nodeID, actorID interface{}) string

NewPath builds a two-segment dotted path "nodeID.actorID".

Types

type ActorPath added in v1.3.0

type ActorPath struct {
	NodeID  string
	ActorID string
	ChildID string
}

func NewActorPath added in v1.3.0

func NewActorPath(nodeID, actorID, childID string) *ActorPath

NewActorPath creates an ActorPath from individual components. Pass empty string for childID when targeting a parent Actor.

func ToActorPath added in v1.3.0

func ToActorPath(path string) (*ActorPath, error)

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

func (p *ActorPath) IsChild() bool

IsChild returns true if this path targets a child Actor.

func (*ActorPath) IsParent added in v1.3.0

func (p *ActorPath) IsParent() bool

IsParent returns true if this path targets a parent (non-child) Actor.

func (*ActorPath) String added in v1.3.0

func (p *ActorPath) String() string

String reconstructs the dotted path notation: "nodeID.actorID" or "nodeID.actorID.childID".

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

func (*Component) Name() string

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

func (p *Message) Clone() *Message

Clone creates a shallow copy for child Actor forwarding. Session, Args and ChanResult are intentionally shared.

func (*Message) Marshal added in v1.5.2

func (p *Message) Marshal() ([]byte, error)

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

func (p *Message) TargetPath() *ActorPath

TargetPath lazily parses the Target field into an ActorPath. Result is cached across the message lifetime and cleared on Recycle.

func (*Message) Unmarshal added in v1.5.2

func (p *Message) Unmarshal(data []byte) error

Unmarshal deserializes cross-process transfer data back into Message.

type OnConnectFunc added in v1.3.0

type OnConnectFunc func(conn net.Conn)

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.

type SID

type SID = string // session unique id

type UID

type UID = int64 // user unique id

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL