core

package module
v0.4.27 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: LGPL-2.1 Imports: 22 Imported by: 59

README

Golaxy Core

English | 简体中文

Golaxy Core is the execution kernel and programming-model foundation of the Golaxy Distributed Service Development Framework. It hosts EC (Entity-Component) business objects inside Actor-style serialized Runtime domains and provides lifecycles, prototypes, entity trees, in-process events, add-ins, structured concurrency, and Future continuations.

Core determines how business code executes and who owns state. Framework connects that execution model to configuration, logging, RPC, Gate, GAP/GTP, NATS, ETCD, databases, and other production infrastructure.

Contents

Positioning

Core is a stateful business execution kernel that can be embedded independently in a Go process. It is also a direct code dependency of the higher-level Framework. The three layers have distinct responsibilities:

Layer Primary responsibility Typical contents
Golaxy Core In-process execution, state ownership, and business-object lifecycles Service, Runtime, Entity, Component, Prototype, Event, Scope, Future, Add-in
Golaxy Framework Distributed service assembly and infrastructure integration Application bootstrap, configuration, logging, RPC, Gate, GAP/GTP, NATS, ETCD, databases
Golaxy Scaffold Game-project scaffold and build-time tooling Protobuf code generation for Go/Godot, plus Excel-table schema, code, and data processing
Application services Product services and deployment structure Player, room, battle, and scene workloads reached through long-lived connections, plus independent HTTP friend, mail, and operations services

Core itself does not provide network listeners, RPC transport, service discovery, message brokers, database drivers, or a configuration center. Use Framework above Core when those features are required, or implement custom add-ins to integrate external systems.

Friend and mail systems are common HTTP application services, not built-in Scaffold modules. Scaffold bootstraps projects and generates build artifacts; it does not implement product-domain services.

Good fits
  • Stateful game-server objects such as players, rooms, battles, scenes, NPCs, and guilds.
  • Simulation, remote-control, digital-twin, and real-time collaboration systems that need stable identities and ordered execution.
  • Backends that decompose complex objects into composable components while strictly controlling where concurrent writes happen.
  • Long-running processes that need both event-driven tasks and fixed-rate frame updates.
What it is not
  • Not one goroutine per Entity: a Runtime manages a group of entities that share one serialized task queue.
  • Not a conventional data-oriented ECS: Core EC centers on object lifecycles and component composition rather than global System queries and batch processing.
  • Not a durable Actor system: Core does not provide message journaling, crash recovery, cross-process mailboxes, or automatic state persistence.
  • Not a general HTTP/CRUD framework: ordinary stateless requests are often simpler with standard HTTP tools; Core is most useful for long-lived business state that requires ordered updates.

Key capabilities

  • Service scope: manages the parent Context, shutdown barrier, prototype libraries, global entity index, and service add-ins.
  • Actor-style Runtime: serializes tasks, entity lifecycles, and optional frame updates on one running goroutine; synchronous events emitted during that work run on the same goroutine.
  • EC business model: Entity supplies identity, scope, and lifecycle; Component supplies composable behavior and state.
  • Prototype system: declares entity types, default scope, metadata, and built-in component compositions before constructing instances.
  • Entity tree: maintains parent-child relationships within one Runtime, with attach, detach, move, post-order removal, and ordered traversal.
  • Async coordination: uses Submit / Post for Actor mailbox delivery, Scope / Spawn for background-task lifetimes, Future / Promise for one-shot results, and ContinueOn for returning continuations to a Runtime.
  • Synchronous events: offers an in-process signal/slot system with priorities, recursion policies, managed unbinding, and code generation.
  • Add-in extension: distinguishes fixed-startup Service add-ins from hot-pluggable Runtime add-ins.
  • Lifecycle, health, and statistics: drives Service, Runtime, Entity, Component, and Add-in lifecycles and exposes Scope, Submit/Post/Frame queue, rejected-wait, and frame statistics.

Architecture

flowchart TB
    Host[Host application] --> ServiceObject[core.Service]
    ServiceObject --> ServiceContext[service.Context]
    ServiceContext --> PrototypeLibraries[EntityLib / ComponentLib]
    ServiceContext --> ServiceAddins[Service add-ins]
    ServiceContext --> GlobalIndex[Global Entity index]

    subgraph RuntimeDomain[Runtime Actor serialized execution domain]
        RuntimeObject[core.Runtime] --> RuntimeContext[runtime.Context]
        ExternalCaller[External caller] -->|Submit or Post| TaskQueue[Actor mailbox]
        FrameScheduler[optional frame scheduler] -->|frame task| TaskQueue
        TaskQueue --> RuntimeLoop[Runtime goroutine]
        RuntimeLoop --> RuntimeContext
        RuntimeContext --> LocalManager[local EntityManager]
        RuntimeContext --> EntityTree[EntityTree]
        RuntimeContext --> RuntimeAddins[Runtime add-ins]
    end

    ServiceContext --> RuntimeObject
    LocalManager --> Entity[Entity]
    Entity --> Component[Components]
    LocalManager -.->|Scope_Global| GlobalIndex

    subgraph AsyncWork[Scope-owned background work]
        LifetimeScope[Service / Runtime / Entity / Component Scope] --> SpawnTask[Spawn goroutine / I/O]
        SpawnTask --> Promise[Promise completes Future]
    end

    ServiceContext --> LifetimeScope
    Promise -->|ContinueOn| TaskQueue
Core objects
Object Responsibility Concurrency model
core.Service Drives service startup, heartbeat, shutdown, and Service add-in lifecycles. Its worker loop runs in a dedicated goroutine.
service.Context Holds service resources, prototype libraries, the global entity index, and the shutdown barrier. Individual capabilities have specific rules; the global entity index is concurrency-safe.
core.Runtime Drives the task queue, frame loop, GC, entities, and Runtime add-ins. One Runtime owns one serialized running goroutine.
runtime.Context Exposes Runtime-local objects and current execution capabilities. Direct local-state access is restricted to the owning Runtime goroutine.
runtime.ConcurrentContext Exposes a Runtime subset usable from other goroutines. Cross-goroutine work returns through Submit or Post.
ec.Entity A business object with an ID, scope, metadata, component collection, and tree-node state. Ordinary methods belong to the Runtime serialization domain.
ec.ConcurrentEntity Exposes ID, prototype, Context, and termination state through a concurrent view. Safe to read across goroutines; mutation must still return to the Runtime.
ec.Component A unit of business behavior or state attached to an Entity. Lifecycle and state mutation belong to the Runtime serialization domain.
ec.ConcurrentComponent Exposes the component ID, name, concurrent Runtime Context, and Component Lifetime Scope. Usable across goroutines; does not expose State, Enabled, Entity, or Destroy.

Actor + EC execution model

Runtime is the Actor boundary

The Actor boundary in Core is the Runtime, not an individual Entity. A Runtime owns one task queue, one local entity manager, one entity tree, and zero or more entities. They all share the same serialized execution domain.

sequenceDiagram
    participant Source as External goroutine / timer / I/O
    participant ResultFuture as Future
    participant Queue as Runtime Actor mailbox
    participant RuntimeLoop as Runtime goroutine
    participant Model as Entity / Components
    Source->>Queue: Submit or Post
    Queue->>RuntimeLoop: Dequeue in order
    RuntimeLoop->>Model: Execute logic and mutate state
    Model-->>RuntimeLoop: Return async.Result
    RuntimeLoop-->>ResultFuture: Complete Submit Future
    ResultFuture->>Queue: ContinueOn enqueues continuation
    Note over Queue,RuntimeLoop: Frame updates, entity lifecycles, and ordinary calls share one boundary

This has several direct consequences:

  • Ordinary tasks, lifecycle callbacks, and frame callbacks do not run concurrently inside one Runtime, so their business state normally needs no locks.
  • Placing multiple entities in one Runtime gives them a shared order of execution and a shared single-thread throughput limit.
  • Entities do not create goroutines automatically, and there is no independent mailbox per Entity.
  • Code outside the Runtime must not directly mutate entities, components, the entity tree, or Runtime add-ins. Use Submit when a result is needed, Post for fire-and-forget delivery, or a Service call by global Entity ID.
  • Use Spawn with an owning object that provides an AsyncScope() for blocking I/O and independent computation. A background function must not touch Runtime-local state directly; use ContinueOn to enqueue result handling back onto the Runtime.
  • Submit, Post, and ContinueOn always enqueue, even when called from the owning Runtime, so the Actor ordering boundary remains consistent.
Local and global Entity addressing

Every Entity exists in the local EntityManager of its owning Runtime:

  • Scope_Local: the Entity is visible only through the local Runtime index.
  • Scope_Global: the Entity is also registered in the concurrency-safe Service-level index.
  • service.Context.Submit(entityId, ...) or Post(entityId, ...) resolves a ConcurrentEntity from the global index, then enqueues work onto the target Runtime.
  • “Global” in Core means addressable across runtimes within the same Service process. Cross-node addressing belongs to Framework distributed-entity and RPC capabilities.

Lifecycles

Service lifecycle

core.NewService emits Birth synchronously while binding a service.Context. Calling Run starts the worker loop:

Birth → Starting → Started → Heartbeat* → Terminating → Terminated

Stage Key behavior
Birth The Service exists; declare prototypes, install Service add-ins, or prepare startup resources here.
Starting Starts prototype watchers, freezes the Service add-in manager, and initializes add-ins in installation order.
Started The Service is running; runtimes are commonly created here.
Heartbeat Emits once per second.
Terminating The Context is canceled; closes the wait-group entry point and waits for runtimes and other children.
Terminated Service add-ins have shut down in reverse order and the termination Signal completes.

A Service can run only once, and a service.Context can be bound to only one core.Service.

Runtime lifecycle

core.NewRuntime emits Birth synchronously while binding a runtime.Context. AutoRun defaults to false; when enabled, Run is called after all Birth handlers finish.

Birth → Starting → Started → Tasks / Frames / GC → Terminating → Terminated

Stage Key behavior
Birth The Runtime object and task queue exist; pre-start Runtime add-ins may be installed.
Starting Activates installed Runtime add-ins and connects EntityManager lifecycle events.
Started Entities can be created and activated. Entities added before startup are activated here as well.
Running Serially handles calls, frame tasks, and entity lifecycles, and periodically runs Runtime GC.
Terminating The Context is canceled and the task queue has been closed and drained; entities are then destroyed in reverse order.
Terminated The wait group is empty, Runtime add-ins are stopped, managed event handles are unbound, and the termination Signal completes.

A runtime.Context can be bound to only one core.Runtime, and a Runtime can run only once.

Entity and Component lifecycles

The one-way Entity state chain is:

Born → Entered → Awakened → Starting → Alive → Leaving → Shutting → Dead → Destroyed

The primary Component state chain is:

Born → Attached → Awakened → Enabling → Starting → Alive → Detaching → Shutting → Disabling → Dead → Destroyed

A disabled Component enters Idle. Enabling it again invokes OnEnable and returns it to Alive, but Start is not repeated.

Object Activation callbacks Frame callbacks Deactivation callbacks
Entity Awake()Start() Update()LateUpdate() Shut()Dispose()
Component Awake()OnEnable()Start() Update()LateUpdate() Shut()OnDisable()Dispose()

Important ordering rules:

  1. Entity Awake runs before the Awake callbacks of its built-in components.
  2. Component Awake, OnEnable, and Start run as separate phases; each phase traverses components in insertion order, followed by Entity Start.
  3. During destruction, Entity Shut runs first; components run Shut, OnDisable, and Dispose in reverse insertion order; Entity Dispose runs last.
  4. Awake, Start, Shut, and Dispose run at most once. OnEnable and OnDisable may repeat as enabled state changes.
  5. Adding components dynamically to a running Entity synchronously advances the new component activation flow.
  6. Destroying an Entity closes its Entity Scope, cancels owned background tasks, removes it from the tree and indexes, and automatically unbinds managed Entity and Component event handles.
  7. Removing a Component, or destroying it with its Entity, closes that Component's Lifetime Scope. SetEnabled(false) does not close the Scope, so the same lifetime remains available after re-enabling.

Runtime scheduling and frame loop

Task queue

The Runtime mailbox distinguishes Submit, Post, and internal Frame tasks. One Runtime goroutine executes all three serially.

  • The default queue is unbounded. Capacity=128 matters only after switching to bounded mode.
  • Submit allocates a Future. A full bounded queue or a closed queue completes that Future with the enqueue error.
  • Post is a no-Future fire-and-forget path. It synchronously reports enqueue errors such as ErrTaskQueueFull and ErrTaskQueueClosed, but has no execution result.
  • SubmitDelegate, SubmitDelegateVoid, and PostDelegate retain Delegate / DelegateVoid invocation support.
  • Post enters the mailbox even when called by the owning Runtime, so it can avoid synchronous reentrancy; it does not guarantee next-frame execution. Core currently has no separate deferred/next-frame scheduling semantic.
  • Shutdown drains tasks that were already accepted, then performs a final GC pass.
  • Runtime.Stats().Tasks exposes Accepted, Queued, Running, Completed, Canceled, Panicked, RejectedClosed, and RejectedFull for Submit, Post, and Frame independently.
  • Runtime.Stats().Health.LastProgressTime records the most recent task start or completion time. A Service-level monitor can combine it with the per-category Running counters to detect a Runtime that has stopped making progress; Core does not keep one resident watchdog goroutine per Runtime.

An unbounded queue prevents immediate rejection during a transient burst, but a backlog consumes memory and increases latency. Production systems should monitor Queued, Running, rejection counters, and Health.LastProgressTime, and apply admission control at external entry points.

Frame loop

The frame loop is enabled by default at a target of 30 FPS with no frame limit. Disable it to use a Runtime as a purely message-driven Actor:

core.With.Runtime.Frame(
	core.With.Frame.Enabled(false),
)

With the frame loop enabled:

  • The scheduler puts frame tasks on the same queue, preserving serialization between Update, LateUpdate, and ordinary calls.
  • Each frame emits FrameLoopBegin and FrameUpdateBegin, runs every Update and LateUpdate, then emits FrameUpdateEnd and FrameLoopEnd.
  • The scheduler waits for the current frame task to finish, so multiple frames never execute concurrently.
  • Blocking tasks or expensive frame callbacks reduce actual FPS. Frame() exposes current FPS, frame counts, and recent timings.
  • Setting TotalFrames > 0 automatically terminates the Runtime after that number of frames.
Runtime GC

Runtime GC runs every 10 seconds by default and once more during shutdown:

  • runtime.Context.CollectGC collects objects that implement runtime.GC and currently return NeedGC() == true.
  • With.Runtime.CustomGC can run application-specific cleanup after built-in cleanup.
  • Runtime GC is deferred cleanup for framework objects; it does not replace the Go garbage collector.

Entities, components, and prototypes

Prototypes

Prototypes keep reusable construction definitions in the Service scope:

Object Purpose
ComponentLib Registers construction prototypes by fully qualified Go component type; repeated declaration of the same named type reuses the existing object.
EntityLib Registers Entity compositions by business prototype name; redeclaring the same name replaces the previous version.
ComponentDescriptor Configures a built-in component name, removability, and metadata.
EntityDescriptor Configures the Entity instance type, default Scope, first-touch behavior, component-ID policy, and metadata.
BuildEntityPT Declares an Entity Prototype through a fluent API.
BuildEntity Constructs an Entity from a declared Prototype and adds it to the current Runtime.

EntityLib and ComponentLib use read-only snapshots for concurrent queries. Their Watch APIs deliver the current snapshot followed by later declarations.

Entity
  • If no persistent ID is supplied, an ID is generated when the Entity enters a Runtime.
  • Both Entity and Prototype default to Scope_Global.
  • Meta carries business metadata keyed by strings.
  • Event handles stored in Managed() are unbound automatically during destruction.
  • Terminated() completes after the Entity reaches Destroyed.
  • Destroy() is a request; the owning Runtime performs removal and lifecycle advancement.
Component
  • One Entity may contain multiple components with the same name. GetComponent returns the first, while GetComponents returns all of them.
  • Built-in components are not dynamically removable by default. Enable removal with ComponentDescriptor.SetRemovable(true).
  • Components added dynamically at runtime are removable by default.
  • Components reuse the Entity ID by default. Enable ComponentUniqueID to allocate an independent ID for every Component.
  • SetEnabled(false) unbinds frame updates and invokes OnDisable; enabling again invokes OnEnable.
  • AsyncScope() returns the Component Lifetime Scope; removal closes it, while disabling keeps it alive.
  • ConcurrentComponent is the concurrency-safe narrow view of a Component; business state must still be accessed on the Runtime through Submit, Post, or ContinueOn.
  • ComponentAwakeOnFirstTouch defers component awakening until first access.
  • Event handles stored in Managed() are unbound automatically during component destruction.
EntityTree

Every Runtime exposes an EntityTree with a virtual forest root:

  • MakeRoot attaches a free Entity to the forest root.
  • AddChild, DetachNode, and MoveNode manage relationships and prevent cycles.
  • RemoveNode removes a subtree relationship in post-order but does not destroy any Entity.
  • Destroying an Entity automatically removes the tree relationships for that Entity and its subtree.
  • Child traversal preserves insertion order and supports forward, reverse, filter, and count operations.
  • EntityTree is not concurrency-safe and must be used on the owning Runtime goroutine.

Async programming

Core separates asynchronous behavior into five independent capabilities instead of making one type carry results, streams, lifecycles, and Actor scheduling at once:

Capability Type / API Semantics
One-shot result Promise / Future One async.Result, replayable to any number of consumers after completion.
Result-free completion Completer / Signal Expresses only “completed”; used for Service, Runtime, and Entity lifecycles.
Continuous data Emitter / Stream Multiple Result values with single-consumer semantics; multiple readers compete for items.
Background-task lifetime Scope / Spawn Binds goroutine cancellation, rejection after close, joining, and statistics to an owning object.
Actor continuation ContinueOn Subscribes to a Future and re-enqueues state mutation onto a target Runtime.
Future and Promise

Future is a non-generic, one-shot, replayable consumer view. Promise is its single-completion producer view:

promise, future := async.NewPromise()

go func() {
	value, err := load()
	promise.Resolve(async.NewResult(value, err))
}()

result := future.Wait(context.Background())
sameResult := future.Wait(context.Background()) // immediately replays the same result
  • Resolve has one-completion semantics; only the first completer receives true.
  • TryGet reads without blocking, Wait waits for completion or Context cancellation, and Done exposes the shared completion channel.
  • OnComplete registers a completion subscription. If the Future has completed, the callback runs immediately on the subscribing goroutine.
  • Completion callbacks run on the completing goroutine outside the state lock and must return quickly. Use ContinueOn when Actor state must change.
  • A Future stores its result, diagnostic ID, and completion-executor ID directly. It does not start a polling or timeout-checking goroutine.
Signal and Stream

Signal carries no Result, making it suitable for lifecycles where only completion matters:

terminated := runtime.Run()
if err := terminated.Wait(ctx); err != nil {
	return err
}

Stream specifically represents continuous sources such as timer ticks and Channel bridges:

ticks := core.Every(ctx, time.Second)
for {
	result, ok := ticks.Next(ctx)
	if !ok {
		break
	}
	_ = result.Value.(time.Time)
}

A Stream is a single-consumer stream, not a broadcast bus. Close wakes blocked producers and closes the data channel safely after registered senders exit. Use event or a higher-level message facility when broadcast is required.

Scope and Spawn

Service, Runtime, Entity, and Component each expose a Lifetime Scope:

flowchart LR
    ServiceScope[Service Scope] --> RuntimeScope[Runtime Scope]
    RuntimeScope --> EntityScope[Entity Scope]
    EntityScope --> ComponentScope[Component Scope]
    ComponentScope --> BackgroundTask[Spawn task]
    ComponentScope -->|Component removal| CancelTask[Cancel and reject new tasks]

A Scope provides:

  1. A cancelable Context for owned tasks.
  2. Rejection of new tasks after the owner closes.
  3. Spawned, Active, Completed, Canceled, and Rejected statistics.
  4. Done() for joining all registered tasks.

Scope.Close cannot forcibly kill a goroutine; a task must observe the Context it receives. A Component Scope closes on removal, but not on SetEnabled(false). Entity, Runtime, and Service scopes close with their respective lifecycles.

Service and Runtime scopes are created with their respective Contexts. An Entity creates its Scope once when it binds to its owning Runtime and directly uses the Scope Context as its Entity Context, avoiding an additional cancellation layer. A Component Scope is created when the Component enters the lifetime of its Entity's Runtime. Every Scope closes synchronously with its owner lifecycle.

future := core.Spawn(
	component,
	func(ctx context.Context, _ ...any) async.Result {
		data, err := repository.Load(ctx, playerID)
		return async.NewResult(data, err)
	},
)
Submit, Post, and ContinueOn
API Future Execution location Purpose
Submit / SubmitDelegate Yes Target Runtime goroutine Actor tasks that produce a business result.
SubmitVoid / SubmitDelegateVoid Yes Target Runtime goroutine No business value, but execution errors or completion still matter.
Post / PostDelegate No Target Runtime goroutine Fire-and-forget messages where only successful enqueue matters.
Spawn / SpawnVoid Yes New goroutine Blocking I/O or independent computation; must not mutate Runtime-local state directly.
ContinueOn and Delegate/Void variants Yes Target Runtime goroutine Serial Actor-state updates after a Future completes.
After / At Yes Timer callback One-shot timed results.
Every / FromChan Stream Bridge goroutine Continuous ticks or Channel data.

The complete “background I/O → Actor continuation” pattern is:

loadFuture := core.Spawn(
	component,
	func(ctx context.Context, _ ...any) async.Result {
		data, err := repository.Load(ctx, playerID)
		return async.NewResult(data, err)
	},
)

next := core.ContinueOn(
	component,
	loadFuture,
	func(ctx runtime.Context, result async.Result, _ ...any) async.Result {
		if result.Error != nil {
			return result
		}
		component.Data = result.Value.(*PlayerData)
		return async.NewResult(nil, nil)
	},
)

ContinueOn checks the owning Scope when subscribing, enqueuing, and immediately before execution. Queue closure, insufficient capacity, an inactive owner, Scope closure, and continuation panics are reported through the returned Future. Future completion triggers a lightweight subscription directly, so a fast RPC response needs no extra waiter goroutine and incurs no polling delay.

Future combinators

Combinators use completion subscriptions, atomic counters, and one-completion guards. They do not start one waiting goroutine per input Future:

API Semantics Empty input
Race First completion, whether successful or failed. ErrNoCandidates
FirstSuccess First success; ErrNoFutureSucceeded if every candidate fails. ErrNoCandidates
All Returns []any in input order; fails immediately on any failure. Successful empty slice
AllSettled Returns every []Result in input order. Successful empty slice
Zip2 Returns async.Pair after both inputs succeed. ErrNoCandidates if either argument is nil
Map Synchronously maps one completed result. Not applicable
FlatMap Flattens a Future selected from one completed result. Not applicable
Timeout The source, Context cancellation, or duration wins—whichever completes first. Not applicable

Combinators cancel only their own subscriptions by default, not source tasks, because a Future may be shared. Close the owning Scope or cancel the supplied Context when the producer itself should stop.

Runtime self-wait protection

Blocking on a pending Future from the Runtime goroutine would freeze the entire Actor. Core stores a completion-executor ID in each Future and implements wait guards on Runtime and Entity contexts:

  • Waiting for a pending Future completed by the same Runtime mailbox immediately returns runtime.ErrRuntimeSelfWait.
  • Waiting for any other pending Future with a Runtime Context immediately returns runtime.ErrBlockingWaitInRuntime.
  • A completed Future remains safe to read immediately through TryGet or Wait.
  • Runtime.Stats().Health.LastWaitRejectID retains the most recently rejected Future ID for diagnosis.

This detects known Future self-waits. A business callback, synchronous I/O call, or infinite loop that stalls for another reason is observable when a task category remains Running while Health.LastProgressTime stops advancing, and should be checked by an external monitor.

Events and code generation

The event package provides in-process synchronous signal/slot events:

  • An event dispatches synchronously on the emitter's current goroutine. It does not enter the Runtime queue or cross a process boundary.
  • Subscribers run in ascending priority; equal priorities preserve binding order.
  • Event, Handle, and ManagedHandles are not concurrency-safe. The caller must serialize their use.
  • Handle.Unbind() precisely removes one binding. Entity, Component, and runtime.Context Managed() collections can own handles for automatic cleanup.
  • Subscriber panic recovery can be enabled, with errors reported non-blockingly through an error channel.
  • Recursion policies are Allow, Disallow, Discard, SkipReceived, and ReceiveOnce. The default recursion-depth limit is 128.

Use eventc to generate type-safe bind helpers, handlers, emitters, and event tables:

//go:generate go run git.golaxy.org/core/event/eventc event
//go:generate go run git.golaxy.org/core/event/eventc eventtab --name=myEventTab

Typical workflow:

  1. Declare event interfaces in a *_event.go file.
  2. Add the required go:generate directives.
  3. Use +event-gen:* and +event-tab-gen:* comments to adjust generation.
  4. Run go generate ./....

In-repository references:

The repository also contains stringer directives. Install stringer and ensure $GOBIN or $GOPATH/bin is on PATH before repository-wide generation:

go install golang.org/x/tools/cmd/stringer@latest
go generate ./...

Add-in system

Add-ins attach cross-cutting capabilities to a Service or Runtime without hard-coding their implementations into Core.

Property Service add-in Runtime add-in
Installation window Before Service enters Starting Before startup or while running
Manager concurrency Immutable snapshots support concurrent install, uninstall, and lookup before startup No concurrency protection; callers must serialize operations, using the Runtime goroutine while running
Activation Initialized in installation order during Service Starting Preinstalled items activate during Runtime Starting; runtime installation activates synchronously
Uninstall Application code cannot uninstall after the manager freezes Can be hot-uninstalled while running
Shutdown Closed in reverse order when Service stops Deactivated on uninstall or Runtime shutdown
Typical use Shared configuration, logging, database pools, discovery clients Runtime-local caches, entity helper indexes, frame-related extensions

An Add-in moves one way through Loaded → Running → Unloaded. Lifecycle contracts include:

  • General: LifecycleAddInInit, LifecycleAddInShut
  • Service: LifecycleServiceAddInInit, LifecycleServiceAddInShut
  • Runtime: LifecycleRuntimeAddInInit, LifecycleRuntimeAddInShut
  • Runtime event subscription: LifecycleAddInOnRuntimeRunningEvent

The define package declares type-safe add-in definitions and exposes consistent Install, Uninstall, Require, and Lookup operations:

  • Require returns only an add-in in Running state and panics when unavailable.
  • Lookup requires only that the manager still holds the add-in; it does not guarantee activation.
  • The default name is the fully qualified interface or instance type name. Its ID is an FNV-1a hash of that name.

Context, errors, and shutdown

Context hierarchy
  • A Service Context derives from context.Background() by default.
  • A Runtime Context derives from its owning Service Context by default.
  • An Entity Scope derives directly from its owning Runtime Context, and the Entity Context reuses that Scope Context.
  • Service, Runtime, Entity, and Component expose separate Lifetime AsyncScope() values; lower-level scopes are canceled with their parent Context.
  • Parent cancellation propagates downward, but Terminated() completes only after the corresponding object finishes cleanup.
Shutdown barrier

Service and Runtime contexts both carry a WaitGroup barrier:

  • Join(delta) registers work that must finish before host shutdown.
  • Once cleanup begins, the barrier closes and rejects new positive increments.
  • Done() completes one registered unit.
  • Terminate() requests cancellation; Terminated() means cleanup has actually finished.
  • Starting a Runtime automatically joins its parent Service barrier, so Service waits for all runtimes to exit.

Use the WaitGroup for host-level external resources. Prefer AsyncScope for new background business tasks. Service and Runtime shutdown close and join their scopes before closing and waiting on the legacy barrier.

Panic handling

Service and Runtime contexts default to AutoRecover=false. With PanicHandling(true, reportError), framework-managed lifecycle, task, and event callbacks attempt to recover panics and write stack-bearing errors non-blockingly to reportError.

Recovery prevents the worker loop from failing immediately; it does not make a partially executed business operation transactional. Callbacks should still preserve explicit invariants and be designed for failure.

Unsafe APIs

UnsafeContext, UnsafeEntity, UnsafeRuntime, and similar entry points exist for internal assembly, generated code, and advanced integrations. They may bypass lifecycle or threading boundaries and are not the preferred APIs for ordinary business code.

Requirements and installation

  • Go version: follow go.mod; the current module targets Go 1.25.
  • Module path: git.golaxy.org/core
  • License: GNU Lesser General Public License v2.1

Install:

go get git.golaxy.org/core@latest

Quick start

This minimal example creates a Service, declares an Entity Prototype, starts a Runtime without a frame loop, creates an Entity, and cancels the parent Context for an ordered shutdown.

package main

import (
	"context"
	"log"
	"time"

	"git.golaxy.org/core"
	"git.golaxy.org/core/ec"
	"git.golaxy.org/core/runtime"
	"git.golaxy.org/core/service"
)

type PlayerState struct {
	ec.ComponentBehavior
}

func (p *PlayerState) Awake() {
	log.Printf("player %s awake", p.Entity().Id())
}

func main() {
	parent, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	svcCtx := service.NewContext(
		service.With.Context(parent),
		service.With.Name("game"),
		service.With.RunningEventCB(func(ctx service.Context, event service.RunningEvent, _ ...any) {
			switch event {
			case service.RunningEvent_Birth:
				core.BuildEntityPT(ctx, "player").
					AddComponent(PlayerState{}).
					Declare()

			case service.RunningEvent_Started:
				core.NewRuntime(
					runtime.NewContext(
						ctx,
						runtime.With.Name("player-runtime"),
						runtime.With.RunningEventCB(func(ctx runtime.Context, event runtime.RunningEvent, _ ...any) {
							if event != runtime.RunningEvent_Started {
								return
							}

							if _, err := core.BuildEntity(ctx, "player").New(); err != nil {
								log.Printf("create player: %v", err)
							}
							cancel()
						}),
					),
					core.With.Runtime.AutoRun(true),
					core.With.Runtime.Frame(core.With.Frame.Enabled(false)),
				)
			}
		}),
	)

	<-core.NewService(svcCtx).Run().Done()
}

See core_test.go for more scenario-style examples.

Default behavior reference

Setting Default Notes
Service parent Context context.Background() Used when no parent is supplied.
Runtime parent Context Owning Service Context Service cancellation propagates to Runtime.
AutoRecover false Panics propagate by default.
Service / Runtime persistent ID Generated Uses uid.Id.
Entity Scope Scope_Global Enters both the Runtime-local and Service-global indexes.
Entity persistent ID Generated when entering Runtime May be overridden during construction.
Component first-touch awakening false Components normally awaken during Entity activation.
Independent Component IDs false Components reuse the Entity ID by default.
Runtime AutoRun false Call Run explicitly or enable AutoRun.
Frame loop Enabled Target is 30 FPS by default.
Frame limit 0 Unlimited.
Task queue Unbounded Bounded mode has a default capacity parameter of 128.
Runtime GC interval 10 seconds Also runs once during shutdown.
Service heartbeat 1 second Emits RunningEvent_Heartbeat.
Event recursion Allow Maximum depth is 128.

Project layout

.
├── define/          # Type-safe add-in definitions
├── ec/              # Entity, Component, state machines, and entity events
│   └── pt/          # Entity / Component prototypes and concurrent libraries
├── event/           # Synchronous events, handles, recursion control, and eventc
├── extension/       # Add-in contracts shared by Service and Runtime
├── runtime/         # Runtime Context, calls, EntityManager, and EntityTree
├── service/         # Service Context, global entity index, and Service add-ins
├── utils/           # async, corectx, generic, iface, meta, uid, and other utilities
├── async.go         # Submit/Post, Spawn, timer, and stream entry points
├── continue.go      # Future-to-Runtime Actor continuations
├── runtime*.go      # Runtime loop, frame, task queue, GC, and lifecycles
└── service*.go      # Service loop and lifecycle
Package guide
Package Responsibility
/ Public entry points, Service/Runtime drivers, lifecycle contracts, entity builders, and async helpers.
/service Service Context, prototype access, global entity index, cross-Runtime entity calls, and Service add-ins.
/runtime Runtime Context, task scheduling, frame statistics, local EntityManager, EntityTree, and Runtime add-ins.
/ec Entity/Component model, concurrent narrow views, state machines, component management, scopes, and tree-node events.
/ec/pt Entity/Component Prototypes, descriptors, concurrent libraries, and instance construction.
/event Synchronous events, priorities, recursion policies, Handle, ManagedHandles, and event tables.
/event/eventc Type-safe event code generator used through go:generate.
/extension Common Add-in contracts, states, installation, lookup, and dependency helpers.
/define Generic Service, Runtime, and common Add-in definitions.
/utils/async Result, Promise/Future, Signal, Stream, Scope, and waiter-free combinators.
/utils/corectx Shared Service/Runtime Context, AsyncScope, wait-group, and shutdown protocol.
/utils Generic containers, interface caches, metadata, options, type helpers, and UIDs.

Development and verification

Regular checks:

go test ./...
go vet ./...

For concurrency-sensitive changes, also run:

go test -race ./...

core_stress_test.go uses the stress build tag and runs for 120 seconds by default:

go test -tags stress .

Override the stress duration:

go test -tags stress . -args "-stress.duration=10s"

Generate event, event-table, and enum-string code:

go generate ./...

Before committing, confirm that generated *.gen.go and *_string.go files are up to date, and avoid introducing blocking I/O on a Runtime goroutine.

Ecosystem and license

  • Golaxy Framework: distributed communication, RPC, Gate, protocol stack, and infrastructure integration built on Core.
  • Golaxy Scaffold: game-project scaffold centered on Protobuf generation and Excel-table processing.
  • Golaxy Examples: end-to-end examples.

This project is licensed under the GNU Lesser General Public License v2.1.

Documentation

Overview

Package core 提供框架的公共入口与跨包编排能力。

Package core 把 service、runtime、ec、event 和 extension 等子包串联成完整的 运行模型。

典型流程如下:

  1. 用 service.NewContext 创建服务上下文。
  2. 用 BuildEntityPT 或 service.Context.EntityLib() 声明实体原型。
  3. 用 runtime.NewContext 创建运行时上下文。
  4. 用 NewService 和 NewRuntime 启动服务与运行时。
  5. 用 BuildEntity 在运行时中创建实体,并让组件生命周期自动推进。

此外,根包还提供:

  • 实体、组件、插件的生命周期接口;
  • Submit/Post Actor 邮箱调度,以及保留 Delegate/DelegateVoid 的对应变体;
  • Scope/Spawn 结构化后台任务与 ContinueOn Runtime 续体;
  • After、Every 等定时和连续流入口;
  • Service、Runtime、Frame 与 TaskQueue 的选项构造器;
  • 面向框架集成与高级扩展场景的 unsafe 辅助入口。

业务模型与底层数据结构分别位于 ec、runtime、service、event、extension、 define 与 utils 子包中。

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCore     = exception.ErrCore                  // 内核错误。
	ErrPanicked = exception.ErrPanicked              // panic 错误。
	ErrArgs     = exception.ErrArgs                  // 参数错误。
	ErrRuntime  = fmt.Errorf("%w: runtime", ErrCore) // 运行时错误。
	ErrService  = fmt.Errorf("%w: service", ErrCore) // 服务错误。
)
View Source
var (
	ErrTaskQueueClosed = fmt.Errorf("%w: task queue is closed", ErrRuntime) // 任务队列已关闭。
	ErrTaskQueueFull   = fmt.Errorf("%w: task queue is full", ErrRuntime)   // 任务队列已满。
)
View Source
var With _Option

With 汇总 Runtime、Frame、TaskQueue 与 Service 的选项构造器。

Functions

func After added in v0.4.27

func After(ctx context.Context, dur time.Duration) async.Future

After 在 dur 后以当前时间完成 Future;ctx 取消时以 ctx.Err 完成。

func At added in v0.4.27

func At(ctx context.Context, at time.Time) async.Future

At 在指定时间以当前时间完成 Future;ctx 取消时以 ctx.Err 完成。

func ContinueOn added in v0.4.27

ContinueOn 在 future 完成后,把 fun 作为新任务投递到 provider 所属 Runtime。

它在订阅、入队和执行前检查异步 Scope;队列关闭、容量不足、Scope 关闭和回调 panic 都通过返回 Future 报告。回调始终在 Runtime goroutine 中串行执行。

func ContinueOnDelegate added in v0.4.27

func ContinueOnDelegate(
	provider corectx.ConcurrentContextProvider,
	future async.Future,
	fun generic.DelegateVar2[runtime.Context, async.Result, any, async.Result],
	args ...any,
) async.Future

ContinueOnDelegate 是 ContinueOn 的 Delegate 版本。

func ContinueOnDelegateVoid added in v0.4.27

func ContinueOnDelegateVoid(
	provider corectx.ConcurrentContextProvider,
	future async.Future,
	fun generic.DelegateVoidVar2[runtime.Context, async.Result, any],
	args ...any,
) async.Future

ContinueOnDelegateVoid 是 ContinueOnVoid 的 DelegateVoid 版本。

func ContinueOnVoid added in v0.4.27

func ContinueOnVoid(
	provider corectx.ConcurrentContextProvider,
	future async.Future,
	fun generic.ActionVar2[runtime.Context, async.Result, any],
	args ...any,
) async.Future

ContinueOnVoid 在 Runtime 中执行无业务返回值续体,并返回可等待错误的 Future。

func Every added in v0.4.27

func Every(ctx context.Context, dur time.Duration) async.Stream

Every 按 dur 周期持续产出当前时间,直到 ctx 取消。

func FromChan added in v0.4.27

func FromChan[T any](ctx context.Context, ch <-chan T) async.Stream

FromChan 将 ch 中的值转换为 Stream,直到 ch 关闭或 ctx 取消。

func Post added in v0.4.27

Post 将无返回值函数投递到 provider 所属 Runtime,不创建 Future。 仅返回队列关闭、容量不足等同步入队错误。

func PostDelegate added in v0.4.27

func PostDelegate(provider corectx.ConcurrentContextProvider, fun generic.DelegateVoidVar1[runtime.Context, any], args ...any) error

PostDelegate 将无返回值委托投递到 provider 所属 Runtime,不创建 Future。

func Spawn added in v0.4.27

Spawn 在 provider 的生命周期 Scope 中启动后台 goroutine。 fun 不得直接访问 Runtime 局部状态。

func SpawnVoid added in v0.4.27

func SpawnVoid(provider corectx.AsyncScopeProvider, fun generic.ActionVar1[context.Context, any], args ...any) async.Future

SpawnVoid 在 provider 的生命周期 Scope 中启动无业务返回值的后台 goroutine。

func Submit added in v0.4.27

Submit 将有返回值函数投递到 provider 所属 Runtime,并返回执行结果 Future。

func SubmitDelegate added in v0.4.27

SubmitDelegate 将有返回值委托投递到 provider 所属 Runtime。

func SubmitDelegateVoid added in v0.4.27

func SubmitDelegateVoid(provider corectx.ConcurrentContextProvider, fun generic.DelegateVoidVar1[runtime.Context, any], args ...any) async.Future

SubmitDelegateVoid 将无业务返回值委托投递到 provider 所属 Runtime。

func SubmitVoid added in v0.4.27

SubmitVoid 将无业务返回值函数投递到 provider 所属 Runtime,并返回可等待错误的 Future。

func UnsafeRuntime deprecated

func UnsafeRuntime(runtime Runtime) _UnsafeRuntime

Deprecated: UnsafeRuntime 暴露运行时内部能力,仅供框架集成代码使用。

func UnsafeService deprecated

func UnsafeService(service Service) _UnsafeService

Deprecated: UnsafeService 暴露服务内部能力,仅供框架集成代码使用。

Types

type CustomGC

type CustomGC = generic.Action1[Runtime] // 运行时完成内置清理后调用的自定义 GC 函数。

type EntityCreator

type EntityCreator struct {
	// contains filtered or unexported fields
}

EntityCreator 基于已声明原型配置并创建实体。

func BuildEntity added in v0.3.92

func BuildEntity(provider corectx.CurrentContextProvider, prototype string) *EntityCreator

BuildEntity 创建绑定到 provider 当前运行时的实体构建器。 prototype 必须已经在所属服务的实体原型库中声明。

func (*EntityCreator) AssignMeta added in v0.4.9

func (c *EntityCreator) AssignMeta(m meta.Meta) *EntityCreator

AssignMeta 直接采用 m 作为待创建实体的元数据。

func (*EntityCreator) MergeMeta added in v0.4.9

func (c *EntityCreator) MergeMeta(dict map[string]any) *EntityCreator

MergeMeta 合并元数据;同名键会被覆盖。

func (*EntityCreator) MergeMetaIfAbsent added in v0.4.9

func (c *EntityCreator) MergeMetaIfAbsent(dict map[string]any) *EntityCreator

MergeMetaIfAbsent 合并元数据;已有的同名键保持不变。

func (*EntityCreator) New added in v0.3.92

func (c *EntityCreator) New() (ec.Entity, error)

New 根据原型构造实体,并将其加入绑定运行时的实体管理器。

func (*EntityCreator) SetComponentAwakeOnFirstTouch added in v0.3.92

func (c *EntityCreator) SetComponentAwakeOnFirstTouch(b bool) *EntityCreator

SetComponentAwakeOnFirstTouch 设置组件是否延迟到首次访问时进入 Awakened 状态。

func (*EntityCreator) SetComponentUniqueID added in v0.3.92

func (c *EntityCreator) SetComponentUniqueID(b bool) *EntityCreator

SetComponentUniqueID 设置是否为每个组件分配独立 ID。

func (*EntityCreator) SetInstance added in v0.3.92

func (c *EntityCreator) SetInstance(instance ec.Entity) *EntityCreator

SetInstance 设置用于扩展实体能力的自定义实例。

func (*EntityCreator) SetInstanceFace added in v0.3.92

func (c *EntityCreator) SetInstanceFace(face iface.Face[ec.Entity]) *EntityCreator

SetInstanceFace 设置用于扩展实体能力的自定义实例及其接口缓存。

func (*EntityCreator) SetMeta added in v0.3.92

func (c *EntityCreator) SetMeta(dict map[string]any) *EntityCreator

SetMeta 用 dict 替换待创建实体的元数据。

func (*EntityCreator) SetPersistId added in v0.3.92

func (c *EntityCreator) SetPersistId(id uid.Id) *EntityCreator

SetPersistId 设置实体的持久化 ID。

func (*EntityCreator) SetScope added in v0.3.92

func (c *EntityCreator) SetScope(scope ec.Scope) *EntityCreator

SetScope 覆盖原型定义的实体可访问作用域。

type EntityPTCreator added in v0.2.39

type EntityPTCreator struct {
	// contains filtered or unexported fields
}

EntityPTCreator 以链式方式配置并声明实体原型。

func BuildEntityPT added in v0.3.92

func BuildEntityPT(svcCtx service.Context, prototype string) *EntityPTCreator

BuildEntityPT 创建绑定到 svcCtx 实体原型库的构建器。

func (*EntityPTCreator) AddComponent added in v0.2.39

func (c *EntityPTCreator) AddComponent(comp any, name ...string) *EntityPTCreator

AddComponent 向原型追加一个内建组件。 comp 可以是组件实例或 ComponentDescriptor;未指定名称时使用组件类型名。

func (*EntityPTCreator) AssignMeta added in v0.4.25

func (c *EntityPTCreator) AssignMeta(m meta.Meta) *EntityPTCreator

AssignMeta 直接采用 m 作为原型元数据。

func (*EntityPTCreator) Declare added in v0.2.39

func (c *EntityPTCreator) Declare()

Declare 将构建结果注册到服务的实体原型库。

func (*EntityPTCreator) MergeMeta added in v0.4.25

func (c *EntityPTCreator) MergeMeta(dict map[string]any) *EntityPTCreator

MergeMeta 合并原型元数据;同名键会被覆盖。

func (*EntityPTCreator) MergeMetaIfAbsent added in v0.4.25

func (c *EntityPTCreator) MergeMetaIfAbsent(dict map[string]any) *EntityPTCreator

MergeMetaIfAbsent 合并原型元数据;已有的同名键保持不变。

func (*EntityPTCreator) SetComponentAwakeOnFirstTouch added in v0.3.92

func (c *EntityPTCreator) SetComponentAwakeOnFirstTouch(b bool) *EntityPTCreator

SetComponentAwakeOnFirstTouch 设置组件是否延迟到首次访问时进入 Awakened 状态。

func (*EntityPTCreator) SetComponentUniqueID added in v0.3.92

func (c *EntityPTCreator) SetComponentUniqueID(b bool) *EntityPTCreator

SetComponentUniqueID 设置是否为每个组件分配独立 ID。

func (*EntityPTCreator) SetInstance added in v0.3.92

func (c *EntityPTCreator) SetInstance(instance any) *EntityPTCreator

SetInstance 设置该原型用于构造自定义实体的实例或反射类型。

func (*EntityPTCreator) SetMeta added in v0.4.25

func (c *EntityPTCreator) SetMeta(dict map[string]any) *EntityPTCreator

SetMeta 用 dict 替换原型元数据。

func (*EntityPTCreator) SetScope added in v0.3.92

func (c *EntityPTCreator) SetScope(scope ec.Scope) *EntityPTCreator

SetScope 设置由该原型创建的实体可访问作用域。

type FrameOptions added in v0.4.25

type FrameOptions struct {
	Enabled     bool    // 是否启用帧循环。
	TargetFPS   float64 // 目标 FPS;设置时会四舍五入为整数值。
	TotalFrames int64   // 最大运行帧数;0 表示不限制。
}

FrameOptions 定义运行时帧循环的选项。

type LifecycleAddInInit added in v0.3.66

type LifecycleAddInInit interface {
	Init(svcCtx service.Context, rtCtx runtime.Context)
}

LifecycleAddInInit 在插件激活时调用。 服务插件的 rtCtx 为 nil;运行时插件会同时收到所属服务和运行时上下文。

type LifecycleAddInOnRuntimeRunningEvent added in v0.4.25

type LifecycleAddInOnRuntimeRunningEvent = runtime.EventContextRunningEvent

LifecycleAddInOnRuntimeRunningEvent 使运行时插件接收激活后的运行事件。

type LifecycleAddInShut added in v0.3.66

type LifecycleAddInShut interface {
	Shut(svcCtx service.Context, rtCtx runtime.Context)
}

LifecycleAddInShut 在插件停用时调用。 服务插件的 rtCtx 为 nil;运行时插件会同时收到所属服务和运行时上下文。

type LifecycleComponentAwake

type LifecycleComponentAwake interface {
	Awake()
}

LifecycleComponentAwake 在组件进入 Awakened 状态时调用,每个组件最多调用一次。

type LifecycleComponentDispose

type LifecycleComponentDispose interface {
	Dispose()
}

LifecycleComponentDispose 在已唤醒的组件进入 Dead 状态时调用,与 LifecycleComponentAwake 成对。

type LifecycleComponentLateUpdate

type LifecycleComponentLateUpdate = eventLateUpdate

LifecycleComponentLateUpdate 在每帧普通更新结束后接收后置更新。

type LifecycleComponentOnDisable added in v0.3.80

type LifecycleComponentOnDisable interface {
	OnDisable()
}

LifecycleComponentOnDisable 在组件被禁用时调用,与 LifecycleComponentOnEnable 成对。

type LifecycleComponentOnEnable added in v0.3.80

type LifecycleComponentOnEnable interface {
	OnEnable()
}

LifecycleComponentOnEnable 在组件被启用时调用,可随启用状态切换而多次调用。

type LifecycleComponentShut

type LifecycleComponentShut interface {
	Shut()
}

LifecycleComponentShut 在已开始的组件进入 Shutting 状态时调用,与 LifecycleComponentStart 成对。

type LifecycleComponentStart

type LifecycleComponentStart interface {
	Start()
}

LifecycleComponentStart 在已启用组件进入 Starting 状态时调用,每个组件最多调用一次。

type LifecycleComponentUpdate

type LifecycleComponentUpdate = eventUpdate

LifecycleComponentUpdate 在启用帧循环且组件处于 Alive 状态时接收每帧更新。

type LifecycleEntityAwake

type LifecycleEntityAwake interface {
	Awake()
}

LifecycleEntityAwake 在实体进入 Awakened 状态时调用,每个实体最多调用一次。

type LifecycleEntityDispose

type LifecycleEntityDispose interface {
	Dispose()
}

LifecycleEntityDispose 在已唤醒的实体进入 Dead 状态时调用,与 LifecycleEntityAwake 成对。

type LifecycleEntityLateUpdate

type LifecycleEntityLateUpdate = eventLateUpdate

LifecycleEntityLateUpdate 在每帧普通更新结束后接收后置更新。

type LifecycleEntityShut

type LifecycleEntityShut interface {
	Shut()
}

LifecycleEntityShut 在已开始的实体进入 Shutting 状态时调用,与 LifecycleEntityStart 成对。

type LifecycleEntityStart

type LifecycleEntityStart interface {
	Start()
}

LifecycleEntityStart 在实体进入 Starting 状态时调用,每个实体最多调用一次。

type LifecycleEntityUpdate

type LifecycleEntityUpdate = eventUpdate

LifecycleEntityUpdate 在启用帧循环且实体处于 Alive 状态时接收每帧更新。

type LifecycleRuntimeAddInInit added in v0.4.2

type LifecycleRuntimeAddInInit interface {
	Init(rtCtx runtime.Context)
}

LifecycleRuntimeAddInInit 在运行时插件激活时调用。

type LifecycleRuntimeAddInShut added in v0.4.2

type LifecycleRuntimeAddInShut interface {
	Shut(rtCtx runtime.Context)
}

LifecycleRuntimeAddInShut 在运行时插件停用时调用。

type LifecycleServiceAddInInit added in v0.4.2

type LifecycleServiceAddInInit interface {
	Init(svcCtx service.Context)
}

LifecycleServiceAddInInit 在服务插件激活时调用。

type LifecycleServiceAddInShut added in v0.4.2

type LifecycleServiceAddInShut interface {
	Shut(svcCtx service.Context)
}

LifecycleServiceAddInShut 在服务插件停用时调用。

type Runtime

type Runtime interface {
	corectx.CurrentContextProvider
	corectx.ConcurrentContextProvider
	reinterpret.InstanceProvider
	runtime.Callee
	// contains filtered or unexported methods
}

Runtime 驱动单个 Actor 风格运行时的任务队列、实体生命周期和可选帧循环。

func NewRuntime

func NewRuntime(rtCtx runtime.Context, settings ...option.Setting[RuntimeOptions]) Runtime

NewRuntime 创建运行时并将 rtCtx 绑定到该运行时。 同一个运行时上下文只能绑定一次;创建期间会同步触发 RunningEvent_Birth。

func UnsafeNewRuntime deprecated

func UnsafeNewRuntime(rtCtx runtime.Context, options RuntimeOptions) Runtime

Deprecated: UnsafeNewRuntime 仅供框架内部使用,请改用 NewRuntime。

type RuntimeBehavior

type RuntimeBehavior struct {
	// contains filtered or unexported fields
}

RuntimeBehavior 提供 Runtime 的默认实现。 扩展运行时类型时应匿名嵌入该类型,并通过 InstanceFace 传入扩展实例。

func (*RuntimeBehavior) ConcurrentContextCache added in v0.4.27

func (rt *RuntimeBehavior) ConcurrentContextCache() iface.Cache

ConcurrentContextCache 返回可跨 goroutine 使用的上下文接口缓存。

func (*RuntimeBehavior) CurrentContextCache added in v0.4.27

func (rt *RuntimeBehavior) CurrentContextCache() iface.Cache

CurrentContextCache 返回仅供运行时 goroutine 使用的上下文接口缓存。

func (*RuntimeBehavior) InstanceFaceCache added in v0.4.25

func (rt *RuntimeBehavior) InstanceFaceCache() iface.Cache

InstanceFaceCache 返回运行时实例的接口缓存,用于 reinterpret.Cast。

func (*RuntimeBehavior) PushPost added in v0.4.27

func (rt *RuntimeBehavior) PushPost(fun generic.ActionVar1[runtime.Context, any], args ...any) error

func (*RuntimeBehavior) PushPostDelegate added in v0.4.27

func (rt *RuntimeBehavior) PushPostDelegate(fun generic.DelegateVoidVar1[runtime.Context, any], args ...any) error

func (*RuntimeBehavior) PushSubmit added in v0.4.27

func (rt *RuntimeBehavior) PushSubmit(fun generic.FuncVar1[runtime.Context, any, async.Result], args ...any) async.Future

func (*RuntimeBehavior) PushSubmitDelegate added in v0.4.27

func (rt *RuntimeBehavior) PushSubmitDelegate(fun generic.DelegateVar1[runtime.Context, any, async.Result], args ...any) async.Future

func (*RuntimeBehavior) PushSubmitDelegateVoid added in v0.4.27

func (rt *RuntimeBehavior) PushSubmitDelegateVoid(fun generic.DelegateVoidVar1[runtime.Context, any], args ...any) async.Future

func (*RuntimeBehavior) PushSubmitVoid added in v0.4.27

func (rt *RuntimeBehavior) PushSubmitVoid(fun generic.ActionVar1[runtime.Context, any], args ...any) async.Future

func (*RuntimeBehavior) Run

func (rt *RuntimeBehavior) Run() async.Signal

Run 在新 goroutine 中启动运行时循环,并返回运行时终止时完成的 Signal。 运行时只能启动一次;上下文已经取消或运行时已经启动时会 panic。

func (*RuntimeBehavior) Stats added in v0.4.25

func (rt *RuntimeBehavior) Stats() RuntimeStats

Stats 返回 Runtime 的并发安全、近似瞬时统计快照。

func (*RuntimeBehavior) Terminate

func (rt *RuntimeBehavior) Terminate() async.Signal

Terminate 请求停止运行时,并返回运行时终止时完成的 Signal。

func (*RuntimeBehavior) Terminated added in v0.3.33

func (rt *RuntimeBehavior) Terminated() async.Signal

Terminated 返回运行时终止时完成的 Signal。

type RuntimeHealthStats added in v0.4.27

type RuntimeHealthStats struct {
	LastProgressTime int64  // 最近一次开始或完成任务的 UnixNano。
	BlockedFutureID  uint64 // 最近由 Runtime Context 尝试阻塞等待的 Future ID。
	LastWaitRejectID uint64 // 最近一次被自等待规则拒绝的 Future ID。
}

RuntimeHealthStats 描述 Runtime 当前执行健康状态。

type RuntimeOptions

type RuntimeOptions struct {
	InstanceFace                    iface.Face[Runtime] // 自定义运行时实例及其接口缓存。
	AutoRun                         bool                // 是否在 RunningEvent_Birth 后自动启动运行时。
	ContinueOnActivatingEntityPanic bool                // 激活实体发生 panic 后是否继续;为 false 时销毁该实体。
	Frame                           FrameOptions        // 帧循环配置。
	TaskQueue                       TaskQueueOptions    // 任务队列配置。
	GCInterval                      time.Duration       // 两次运行时 GC 之间的最短间隔。
	CustomGC                        CustomGC            // 内置清理完成后执行的自定义 GC。
}

RuntimeOptions 定义创建运行时及其工作循环时使用的选项。

type RuntimeStats added in v0.4.25

type RuntimeStats struct {
	WaitGroupCount  int64
	WaitGroupClosed bool
	Tasks           RuntimeTaskStats
	Scope           async.ScopeStats
	Health          RuntimeHealthStats
}

RuntimeStats 描述 Runtime 的生命周期、邮箱、异步作用域和健康状态快照。 各字段通过独立原子读取获得,不保证是同一时刻的事务快照。

type RuntimeTaskStats added in v0.4.27

type RuntimeTaskStats struct {
	Submit TaskQueueStats
	Post   TaskQueueStats
	Frame  TaskQueueStats
}

RuntimeTaskStats 按 Submit、Post 和 Frame 三种调度语义分类。

type Service

type Service interface {
	reinterpret.InstanceProvider

	// Context 返回绑定的服务上下文。
	Context() service.Context
	// contains filtered or unexported methods
}

Service 编排服务上下文的启动与停止生命周期。

func NewService

func NewService(svcCtx service.Context, settings ...option.Setting[ServiceOptions]) Service

NewService 创建服务并将 svcCtx 绑定到该服务。 同一个服务上下文只能绑定一次;创建期间会同步触发 RunningEvent_Birth。

func UnsafeNewService deprecated

func UnsafeNewService(svcCtx service.Context, options ServiceOptions) Service

Deprecated: UnsafeNewService 仅供框架内部使用,请改用 NewService。

type ServiceBehavior

type ServiceBehavior struct {
	// contains filtered or unexported fields
}

ServiceBehavior 提供 Service 的默认实现。 扩展服务类型时应匿名嵌入该类型,并通过 InstanceFace 传入扩展实例。

func (*ServiceBehavior) Context added in v0.4.25

func (svc *ServiceBehavior) Context() service.Context

Context 返回绑定的服务上下文。

func (*ServiceBehavior) InstanceFaceCache added in v0.4.25

func (svc *ServiceBehavior) InstanceFaceCache() iface.Cache

InstanceFaceCache 返回服务实例的接口缓存,用于 reinterpret.Cast。

func (*ServiceBehavior) Run

func (svc *ServiceBehavior) Run() async.Signal

Run 在新 goroutine 中启动服务循环,并返回服务终止时完成的 Signal。 服务只能启动一次;上下文已经取消或服务已经启动时会 panic。

func (*ServiceBehavior) Stats added in v0.4.25

func (svc *ServiceBehavior) Stats() ServiceStats

Stats 返回服务统计信息的当前快照。

func (*ServiceBehavior) Terminate

func (svc *ServiceBehavior) Terminate() async.Signal

Terminate 请求停止服务,并返回服务终止时完成的 Signal。

func (*ServiceBehavior) Terminated added in v0.3.33

func (svc *ServiceBehavior) Terminated() async.Signal

Terminated 返回服务终止时完成的 Signal。

type ServiceOptions

type ServiceOptions struct {
	InstanceFace iface.Face[Service] // 自定义服务实例及其接口缓存。
}

ServiceOptions 定义创建服务时使用的选项。

type ServiceStats added in v0.4.25

type ServiceStats struct {
	WaitGroupCount  int64 // 尚未完成的等待组任务数。
	WaitGroupClosed bool  // 等待组是否已经关闭并拒绝新任务。
}

ServiceStats 描述服务当前的等待组状态。

type TaskQueueOptions added in v0.4.25

type TaskQueueOptions struct {
	Unbounded bool // 是否使用无界队列。
	Capacity  int  // 有界队列容量;使用无界队列时忽略。
}

TaskQueueOptions 定义运行时任务队列的容量策略。

type TaskQueueStats added in v0.4.25

type TaskQueueStats struct {
	Accepted       int64 // 成功进入队列的任务总数。
	Queued         int64 // 当前仅在队列中等待的任务数。
	Running        int64 // 当前正在执行的任务数。
	Completed      int64 // 已进入终态的任务总数。
	Canceled       int64 // Completed 中因调度上下文取消结束的数量。
	Panicked       int64 // Completed 中恢复过 panic 的数量。
	RejectedClosed int64 // 因队列关闭而拒绝的数量。
	RejectedFull   int64 // 因有界队列容量不足而拒绝的数量。
}

TaskQueueStats 描述一种调度语义的 Runtime 邮箱统计。

type TaskType added in v0.4.25

type TaskType int8

TaskType 标识 Runtime 邮箱中的调度类别。

const (
	TaskType_Submit TaskType = iota // 创建 Future 的可等待任务。
	TaskType_Post                   // 不创建 Future 的 fire-and-forget 任务。
	TaskType_Frame                  // 帧循环内部任务。

)

Directories

Path Synopsis
Package define 为插件声明提供类型安全的辅助定义。
Package define 为插件声明提供类型安全的辅助定义。
ec
Package ec 定义实体—组件模型及其生命周期状态。
Package ec 定义实体—组件模型及其生命周期状态。
pt
Package pt 提供实体与组件原型库。
Package pt 提供实体与组件原型库。
Package event 提供进程内同步信号式事件基础设施。
Package event 提供进程内同步信号式事件基础设施。
eventc command
Command eventc 是 Golaxy 的信号式事件代码生成工具。
Command eventc 是 Golaxy 的信号式事件代码生成工具。
Package extension 定义插件的公共协议与辅助函数。
Package extension 定义插件的公共协议与辅助函数。
Package runtime 定义运行时级上下文。
Package runtime 定义运行时级上下文。
Package service 定义服务级上下文。
Package service 定义服务级上下文。
Package utils 是核心工具包的命名空间根目录。
Package utils 是核心工具包的命名空间根目录。
assertion
Package assertion 提供基于实体组件模型的断言与注入辅助。
Package assertion 提供基于实体组件模型的断言与注入辅助。
async
Package async 提供一次性结果、完成信号、连续流和结构化异步作用域。
Package async 提供一次性结果、完成信号、连续流和结构化异步作用域。
corectx
Package corectx 定义 service 与 runtime 共用的上下文契约。
Package corectx 定义 service 与 runtime 共用的上下文契约。
exception
Package exception 提供带调用位置信息的错误与 panic 辅助。
Package exception 提供带调用位置信息的错误与 panic 辅助。
generic
Package generic 提供框架内部常用的泛型基础设施。
Package generic 提供框架内部常用的泛型基础设施。
iface
Package iface 提供接口缓存与 Face 封装。
Package iface 提供接口缓存与 Face 封装。
meta
Package meta 提供按字符串键排序的元数据映射。
Package meta 提供按字符串键排序的元数据映射。
option
Package option 提供泛型选项构造器。
Package option 提供泛型选项构造器。
reinterpret
Package reinterpret 提供基于实例缓存的接口重新解释。
Package reinterpret 提供基于实例缓存的接口重新解释。
types
Package types 提供反射类型辅助函数。
Package types 提供反射类型辅助函数。
uid
Package uid 提供框架统一使用的全局唯一 ID 类型。
Package uid 提供框架统一使用的全局唯一 ID 类型。

Jump to

Keyboard shortcuts

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