Table of Contents

Class PluginConnectionHost<TConnection>

Namespace
DotBoxD.Pushdown.Services
Assembly
DotBoxD.Pushdown.Services.dll

Accepts ONE plugin connection and owns the per-connection trust-boundary lifecycle: it listens for the connecting peer, mints a PluginSession for it, runs configure to provision that peer (provide host services over the session and return the per-connection object callers await), and disposes the session — revoking and unregistering the kernels that peer owned — when the peer disconnects OR the host is stopped/disposed.

This is the per-connection IPC ceremony every plugin host used to hand-write. Forgetting the dispose-on-disconnect step silently leaks a peer's kernels, so the framework owns it; the host is left with only the genuinely connection-specific work of choosing which services to provide. The helper is opt-in: everything it does is reproducible with public API (Listen(IServerTransport, Action<RpcPeer>, RpcPeerOptions?) / CreateSession() / peer.Provide / peer.Disconnected).

public sealed class PluginConnectionHost<TConnection> : IAsyncDisposable

Type Parameters

TConnection

The per-connection object configure returns (e.g. the control service).

Inheritance
PluginConnectionHost<TConnection>
Implements
Inherited Members

Properties

Connected

Completes when a plugin connects, yielding the object configure returned for it; faults if configure throws; cancels if the host is stopped/disposed before any plugin connects.

public Task<TConnection> Connected { get; }

Property Value

Task<TConnection>

Disconnected

Completes when the connected plugin drops (after its session has been disposed) OR the host is stopped/disposed.

public Task Disconnected { get; }

Property Value

Task

PipeName

The named pipe the plugin peer dials, or empty when started over a non-pipe transport.

public string PipeName { get; }

Property Value

string

Methods

DisposeAsync()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources asynchronously.

public ValueTask DisposeAsync()

Returns

ValueTask

A task that represents the asynchronous dispose operation.

StartAsync(PluginServer, IServerTransport, Func<RpcPeer, PluginSession, TConnection>, RpcPeerOptions?)

Starts listening over any transport (TCP, in-memory, …) — the transport-agnostic form, so a host is not locked to named pipes. Same per-connection lifecycle as the pipe overload; PipeName is empty.

public static Task<PluginConnectionHost<TConnection>> StartAsync(PluginServer server, IServerTransport transport, Func<RpcPeer, PluginSession, TConnection> configure, RpcPeerOptions? options = null)

Parameters

server PluginServer
transport IServerTransport
configure Func<RpcPeer, PluginSession, TConnection>
options RpcPeerOptions

Returns

Task<PluginConnectionHost<TConnection>>

StartAsync(PluginServer, string, Func<RpcPeer, PluginSession, TConnection>, RpcPeerOptions?)

Starts listening on pipeName (a convenience over the transport overload; keeps the high-entropy pipe-name validation). For the connecting peer the host mints a session and invokes configure(peer, session) — where the caller provides its host services over the session and returns the per-connection object surfaced by Connected. The session is disposed automatically when the peer disconnects or the host is stopped/disposed.

public static Task<PluginConnectionHost<TConnection>> StartAsync(PluginServer server, string pipeName, Func<RpcPeer, PluginSession, TConnection> configure, RpcPeerOptions? options = null)

Parameters

server PluginServer
pipeName string
configure Func<RpcPeer, PluginSession, TConnection>
options RpcPeerOptions

Returns

Task<PluginConnectionHost<TConnection>>

StopAsync()

Stops accepting connections and disposes the connected plugin's session. A local stop does not raise the peer's Disconnected event, so this is the cleanup path when the host shuts the listener down while a plugin is still connected; it also completes Connected/Disconnected so no awaiter is left hanging.

public Task StopAsync()

Returns

Task