Table of Contents

Interface IWorldServerService

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

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

public interface IWorldServerService : IFetchByKeyAction<long, WorldServerData>
Inherited Members

Remarks

Execution Strategy: All write operations (PersistAsync, PulseAsync, DeleteAsync) use execution strategy wrappers to handle transient database failures with automatic retry. FromSqlRaw and ExecuteSqlRawAsync calls do not automatically retry without manual wrapping.

Read Operations: Read operations use LINQ queries and are executed via BaseService execution wrappers for consistent exception mapping. Explicit transactions are used only when a write requires multiple database statements.

Error Handling: All database operations return DatabaseResult or DatabaseResult<T> with structured error codes (e.g., STALE_STATE, NOT_FOUND, UNIQUE_VIOLATION, DATABASE_ERROR) for comprehensive, safe error handling.

Methods

DeleteAsync(long, CancellationToken)

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

Parameters

serverId long
cancellationToken CancellationToken

Returns

Task<DatabaseResult>

FetchActiveAsync(float, CancellationToken)

Fetches active world servers that have pulsed within the timeout window. Filters servers by last_pulse timestamp to return only servers that are currently online.

Task<DatabaseResult<List<WorldServerData>>> FetchActiveAsync(float idleTimeoutSeconds = 60, CancellationToken cancellationToken = default)

Parameters

idleTimeoutSeconds float

Idle timeout in seconds before server considered inactive (default 60).

cancellationToken CancellationToken

Cancellation token for async operation.

Returns

Task<DatabaseResult<List<WorldServerData>>>

DatabaseResult containing List of active WorldServerData ordered by name; empty list if no active servers.

Remarks

Operation: LINQ query filtering by last_pulse >= (UtcNow - timeout), ordered by name.

Execution Strategy: BaseService handles retries and centralized exception mapping; explicit transactions are used only when a write requires multiple database statements.

FetchControlStateAsync(long, CancellationToken)

Reads a world server's lock and shutdown state without writing a pulse.

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

Parameters

serverId long

World server row to read.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult<ServerControlState>>

The control state, or NotFound when the row is gone.

Remarks

For scene servers, which host scenes on behalf of a world but do not pulse its row. A world-wide shutdown has to reach them so they can warn their players and clear the world's characters out on the same deadline.

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

Persists a world server registration (insert or update). Uses an insert-first approach and falls back to update on unique constraint conflicts.

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

Parameters

name string

Server name (unique identifier for conflict resolution).

address string

Server IP address or hostname.

port ushort

Server port number.

characterCount int

Current character count on server.

locked bool

Whether server is locked from accepting new connections.

cancellationToken CancellationToken

Cancellation token for async operation.

Returns

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

DatabaseResult containing tuple (ServerId, ServerData) if successful.

Remarks

Operation: Attempts INSERT; on unique violation, loads the existing row and updates it.

Returns: The returned ServerId is populated after SaveChanges completes inside the BaseService execution wrapper.

Returns: Failure if name/address empty or operation fails; Success with (ServerId, ServerData) on success.

PulseAsync(long, int, CancellationToken)

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

Parameters

serverId long
characterCount int
cancellationToken CancellationToken

Returns

Task<DatabaseResult<ServerControlState>>

SetLockedAsync(long, bool, CancellationToken)

Opens or closes this world server to new connections.

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

Parameters

serverId long

World server row to update.

locked bool

True to close it to new arrivals.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DatabaseResult>

Success, or NotFound when the row is gone.

Remarks

The row is the authority; the server adopts it on its next pulse. Locking drains rather than evicts — see Locked.

SetShutdownAsync(long, DateTime?, CancellationToken)

Schedules or cancels this world server's shutdown.

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

Parameters

serverId long

World 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, in the same statement. Cancelling does not unlock it: halting a shutdown and reopening to players are separate decisions.