Table of Contents

Interface ISceneServerService

Namespace
FishMMO.Database.Npgsql.Services.Interfaces
Assembly
FishMMO-DB.dll

Service interface for scene server registration and management operations. Provides async methods for server registration, heartbeat updates, and retrieval.

public interface ISceneServerService : IFetchByKeyAction<long, SceneServerData>
Inherited Members

Remarks

Write operations (Persist*, Pulse*, Delete*) in this service use execution strategies to ensure transient database failures are automatically retried according to the retry policy configured on the DbContext. This is critical because ExecuteSqlRawAsync and FromSqlRaw do not automatically retry on transient failures without an execution strategy wrapper. BaseService provides execution wrappers for retry and centralized exception mapping; explicit transactions are used only when a write requires multiple database statements.

All methods return DatabaseResult or DatabaseResult<T> to provide structured error information through the DatabaseException system, helping distinguish between: - Validation failures (invalid parameters) - Not found scenarios (server doesn't exist) - Database errors (connection issues, constraint violations, timeouts) - Entity not found errors - Unexpected runtime errors

PersistAsync uses atomic UPSERT to prevent race conditions during concurrent registrations.

Methods

DeleteAsync(long, CancellationToken)

Deletes a scene server registration.

Task<DatabaseResult> DeleteAsync(long serverId, CancellationToken cancellationToken = default)

Parameters

serverId long

Server ID to delete.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

A DatabaseResult indicating success or containing a DatabaseException on failure. Returns DatabaseEntityNotFoundException if server doesn't exist.

Remarks

Uses ExecuteSqlRawAsync with execution strategy wrapping to ensure transient database failures are automatically retried.

FetchSceneServersByIDsAsync(List<long>, int, CancellationToken)

Retrieves multiple scene servers by their IDs in batches.

Task<DatabaseResult<IReadOnlyList<SceneServerData>>> FetchSceneServersByIDsAsync(List<long> serverIds, int maxBatchSize = 500, CancellationToken cancellationToken = default)

Parameters

serverIds List<long>

List of server IDs to query.

maxBatchSize int

Maximum number of IDs per database round-trip (500–1000).

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult<IReadOnlyList<SceneServerData>>>

A list of SceneServerData for each found server.

PersistAsync(string, string, ushort, int, bool, CancellationToken)

Persists a scene server registration with atomic UPSERT.

Task<DatabaseResult<(long ServerId, SceneServerData ServerData)>> PersistAsync(string name, string address, ushort port, int characterCount, bool locked, CancellationToken cancellationToken = default)

Parameters

name string

Server name (unique identifier).

address string

Server address.

port ushort

Server port.

characterCount int

Current character count.

locked bool

Whether server is locked.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult<(long ServerId, SceneServerData ServerData)>>

A DatabaseResult<T> containing a tuple with (ServerId, ServerData) on success, or a DatabaseException on failure.

Remarks

Uses FromSqlRaw with RETURNING clause and execution strategy wrapping to ensure transient database failures are automatically retried. Uses PostgreSQL ON CONFLICT for atomic UPSERT with full data return.

PulseAsync(long, int, CancellationToken)

Updates the last pulse timestamp, character count, and lock state for a scene server (heartbeat).

Task<DatabaseResult<ServerControlState>> PulseAsync(long serverId, int characterCount, CancellationToken cancellationToken = default)

Parameters

serverId long

Server ID.

characterCount int

Current character count.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult<ServerControlState>>

A DatabaseResult indicating success or containing a DatabaseException on failure. Returns DatabaseEntityNotFoundException if server doesn't exist.

Remarks

Uses ExecuteSqlRawAsync with execution strategy wrapping to ensure transient database failures are automatically retried. Updates timestamp to current UTC time along with character count and lock state.

SetLockedAsync(long, bool, CancellationToken)

Opens or closes this scene server to new arrivals.

Task<DatabaseResult> SetLockedAsync(long serverId, bool locked, CancellationToken cancellationToken = default)

Parameters

serverId long

Scene server row to update.

locked bool

True to close it.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

Success, or NotFound when the row is gone.

Remarks

A locked scene server is skipped by the world server's routing and stops dequeuing scene-load requests, so it drains as its players leave. Players already on it keep playing. The row is the authority; the server adopts it on its next pulse.

SetShutdownAsync(long, DateTime?, CancellationToken)

Schedules or cancels this scene server's shutdown.

Task<DatabaseResult> SetShutdownAsync(long serverId, DateTime? shutdownAtUtc, CancellationToken cancellationToken = default)

Parameters

serverId long

Scene server row to update.

shutdownAtUtc DateTime?

Absolute UTC stop time, or null to cancel.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

Success, or NotFound when the row is gone.

Remarks

Scheduling also locks the server; cancelling does not unlock it.