Skip to content

v0.35.0 Server-Side API for Meta Services

Choose a tag to compare

@dmitry-lebedev dmitry-lebedev released this 29 Jul 10:21
· 15 commits to main since this release

{Service}ServerApi provides typed invocation of meta-methods from server-side code that is not executing inside a meta-call context (e.g., admin panels, framework grains, background jobs).

await grainFactory.GetServerApi<IProfileService>(playerId).AddResourcesAsync(...);
await factory.GetServerApi<IProfileService>(playerId, "1.4.0").MigrateAsync();  // targeting a specific client version

Invocations pass through the server-side cross-entity entry point, ensuring replay recording, subscriber broadcasting, persistence, and sequence advancement occur as usual. Works on cold entities without active subscribers.

Added

  • {Service}ServerApi + IMetaServerApiFactory (DI handle, registered automatically; IGrainFactory extensions remain available for callers without DI).
  • Optional callerClientVersion parameter to specify which application version the call should execute under (config branch + state migration ceiling).
  • Applying [MetaMethod] to a method within [MetaServiceImpl] exposes it on the service surface—the contract can now be inherited from an interface in an external assembly.

Fixed

  • Security: Methods with Mode = Notification were not validated on the server—forged packets containing their IDs were being dispatched. Validation rules are now unified across all modes (MetaMethodFacts).
  • Server-side calls now honor force-patch fan-out (previously restricted to client RPCs).
  • {Service}ServerApi now retrieves the serializer from the assembly declaring the service rather than the compiling project. Assembly mismatches previously resulted in objects with empty collections silently.
  • [ServiceConfig] accessors now resolve configurations by type rather than by index within the service; on states hosting multiple services, index-based resolution previously targeted the wrong configuration.
  • Config version resolution now defaults to CurrentClientVersion across all code paths—previously, server-side calls to config-bound services failed with "clientAppVersion is required".
  • Server-side calls now execute under the entity owner's version (resolved from persistent subscribers, working for offline players as well) rather than the current server version. When multiple subscribers exist, the lowest version is selected.
  • Configurations are no longer required to be pre-cached—invocations now materialize the configuration for their specified version on demand (fixing previous "no cached config for X" errors).
  • Direct RPCs to entities touched by a CrossOptimistic call no longer hang indefinitely (the sequence tracking key had been defaulting to an empty stateType since v0.33.0).
  • Hosts lacking an IConfigVersionResolver no longer log error messages on every entity activation.