Class PluginSession
Namespace: DotBoxD.Plugins
Assembly: DotBoxD.Plugins.dll
Server-side owner of the kernels installed over one connection. Each kernel it installs is tagged with this session as its owner, so another session cannot replace or mutate it. Disposing the session — e.g. from a transport disconnect handler — revokes and unregisters every kernel it owns.
public sealed class PluginSession : IDisposable, IAsyncDisposableInheritance
Section titled “Inheritance”Implements
Section titled “Implements”Inherited Members
Section titled “Inherited Members”object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()
Extension Methods
Section titled “Extension Methods”Remarks
Section titled “Remarks”The install/stage/promote surface lives in the PluginSession.Install.cs partial.
Methods
Section titled “Methods”Dispose()
Section titled “ Dispose()”Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()DisposeAsync()
Section titled “ DisposeAsync()”Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources asynchronously.
public ValueTask DisposeAsync()Returns
Section titled “Returns”A task that represents the asynchronous dispose operation.
InstallAndWireAsync(PluginPackage, Action<InstalledKernel>, Func<PluginPackage, SandboxPolicy>?, Action<PluginPackage>?, CancellationToken)
Section titled “ InstallAndWireAsync(PluginPackage, Action<InstalledKernel>, Func<PluginPackage, SandboxPolicy>?, Action<PluginPackage>?, CancellationToken)”Installs an event-kernel package owned by this session and wires it in one step,
rolling the install back if validation or wiring fails — the install ceremony every host used to
hand-write. validate runs before install for host route checks;
policy overrides the default install policy; wire is the host’s
routing choice (typically DotBoxD.Plugins.PluginServer.WireHook(DotBoxD.Plugins.Kernel.InstalledKernel,DotBoxD.Plugins.WireOptions) or
DotBoxD.Plugins.PluginServer.WireSubscription(DotBoxD.Plugins.Kernel.InstalledKernel,DotBoxD.Plugins.WireOptions) with host wire options).
The kernel is installed as a non-current instance, wired, and only then promoted to current — all under the session gate. So: a same-id incumbent is not revoked until wiring succeeds (a wiring failure rolls the new instance back by its exact install id with the incumbent still live and current), and a concurrent `DotBoxD.Plugins.PluginSession.Dispose` cannot tear the kernel down mid-wire and leave a dangling handler. On any failure the original exception is rethrown.
Note: during a same-id hot-replace there is a brief window — between wiring the new kernel and promoting it (which revokes the incumbent) — in which both the outgoing and incoming kernels are wired, since pipeline handlers are keyed per kernel instance. A concurrent publish of the same event in that window may be observed by both kernels until promotion completes. (The first install of a given id has no incumbent and so no such window.)
Local-terminal packages use their callback route as replay identity: retrying the same owned package reuses the existing kernel, while reusing the callback route for a different package is rejected.
public ValueTask<InstalledKernel> InstallAndWireAsync(PluginPackage package, Action<InstalledKernel> wire, Func<PluginPackage, SandboxPolicy>? policy = null, Action<PluginPackage>? validate = null, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”package PluginPackage
wire Action<InstalledKernel>
policy Func<PluginPackage, SandboxPolicy>?
validate Action<PluginPackage>?
cancellationToken CancellationToken
Returns
Section titled “Returns”Remarks
Section titled “Remarks”Opt-in convenience over public primitives: hand-write the equivalent with
DotBoxD.Plugins.PluginSession.InstallStagedAsync(DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy,System.Threading.CancellationToken) + your wire action + DotBoxD.Plugins.PluginSession.Promote(DotBoxD.Plugins.Kernel.InstalledKernel) on success /
DotBoxD.Plugins.PluginSession.Uninstall(System.String) by the staged kernel’s DotBoxD.Plugins.Kernel.InstalledKernel.InstallId on failure (passing
the plugin id instead would target the live incumbent in a hot-replace, not the staged kernel). The
validate and policy callbacks run before the session gate is held.
The wire callback runs while the session gate is held, so it must only touch server-side
routing (e.g. DotBoxD.Plugins.PluginServer.WireHook(DotBoxD.Plugins.Kernel.InstalledKernel,DotBoxD.Plugins.WireOptions) / DotBoxD.Plugins.PluginServer.WireSubscription(DotBoxD.Plugins.Kernel.InstalledKernel,DotBoxD.Plugins.WireOptions)) and must
NOT call back into this session (DotBoxD.Plugins.PluginSession.InstallAsync(DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy,System.Threading.CancellationToken) / DotBoxD.Plugins.PluginSession.InstallStagedAsync(DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy,System.Threading.CancellationToken) /
DotBoxD.Plugins.PluginSession.Promote(DotBoxD.Plugins.Kernel.InstalledKernel) / DotBoxD.Plugins.PluginSession.Uninstall(System.String) / DotBoxD.Plugins.PluginSession.Owns(System.String) / DotBoxD.Plugins.PluginSession.TryGetOwned(System.String,DotBoxD.Plugins.Kernel.InstalledKernel@) /
DotBoxD.Plugins.PluginSession.UpdateSettingsAsync(System.String,System.Collections.Generic.IReadOnlyDictionary{System.String,System.Object},System.Boolean,System.Threading.CancellationToken)), which would deadlock on the non-reentrant gate.
InstallAsync(PluginPackage, SandboxPolicy?, CancellationToken)
Section titled “ InstallAsync(PluginPackage, SandboxPolicy?, CancellationToken)”Installs a package owned by this session. The install and the ownership bookkeeping are atomic
with respect to DotBoxD.Plugins.PluginSession.Dispose, so a kernel can never be installed-then-orphaned by a
concurrent disconnect.
public ValueTask<InstalledKernel> InstallAsync(PluginPackage package, SandboxPolicy? policy = null, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”package PluginPackage
policy SandboxPolicy?
cancellationToken CancellationToken
Returns
Section titled “Returns”InstallServerExtensionAsync(PluginPackage, SandboxPolicy?, CancellationToken)
Section titled “ InstallServerExtensionAsync(PluginPackage, SandboxPolicy?, CancellationToken)”Installs a server extension package owned by this session (see
DotBoxD.Plugins.PluginServer.InstallServerExtensionAsync(DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy,System.Threading.CancellationToken)). Same ownership/atomicity guarantees as
DotBoxD.Plugins.PluginSession.InstallAsync(DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy,System.Threading.CancellationToken); the kernel is invoked request/response via
DotBoxD.Plugins.Kernel.InstalledKernel.InvokeServerExtensionAsync(System.Collections.Generic.IReadOnlyList{DotBoxD.Kernels.Sandbox.SandboxValue},System.Threading.CancellationToken) and revoked when the session is disposed.
public ValueTask<InstalledKernel> InstallServerExtensionAsync(PluginPackage package, SandboxPolicy? policy = null, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”package PluginPackage
policy SandboxPolicy?
cancellationToken CancellationToken
Returns
Section titled “Returns”InstallStagedAsync(PluginPackage, SandboxPolicy?, CancellationToken)
Section titled “ InstallStagedAsync(PluginPackage, SandboxPolicy?, CancellationToken)”Installs package owned by this session as a non-current instance: a same-id
incumbent (if any) stays current and un-revoked. Pair with DotBoxD.Plugins.PluginSession.Promote(DotBoxD.Plugins.Kernel.InstalledKernel) once the returned kernel
is wired, or roll it back with DotBoxD.Plugins.PluginSession.Uninstall(System.String) using the returned kernel’s
DotBoxD.Plugins.Kernel.InstalledKernel.InstallId (or by disposing the session). This is the public staging primitive
behind DotBoxD.Plugins.PluginSession.InstallAndWireAsync(DotBoxD.Plugins.PluginPackage,System.Action{DotBoxD.Plugins.Kernel.InstalledKernel},System.Func{DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy},System.Action{DotBoxD.Plugins.PluginPackage},System.Threading.CancellationToken) — it lets a host wire a kernel before it displaces the
incumbent, so the helper’s behavior is reproducible by hand with public API.
public ValueTask<InstalledKernel> InstallStagedAsync(PluginPackage package, SandboxPolicy? policy = null, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”package PluginPackage
policy SandboxPolicy?
cancellationToken CancellationToken
Returns
Section titled “Returns”Owns(string)
Section titled “ Owns(string)”Whether this (non-disposed) session currently owns pluginId.
public bool Owns(string pluginId)Parameters
Section titled “Parameters”pluginId string
Returns
Section titled “Returns”Promote(InstalledKernel)
Section titled “ Promote(InstalledKernel)”Promotes a kernel previously installed via DotBoxD.Plugins.PluginSession.InstallStagedAsync(DotBoxD.Plugins.PluginPackage,DotBoxD.Kernels.SandboxPolicy,System.Threading.CancellationToken) to be the current kernel for its
plugin id, revoking and detaching any prior same-id incumbent only now (so a pre-promotion failure leaves
the incumbent live). Rejects a kernel this session does not own. A local-terminal kernel has no current-kernel
semantics, so promotion is a no-op for it.
public void Promote(InstalledKernel kernel)Parameters
Section titled “Parameters”kernel InstalledKernel
TryGetOwned(string, out InstalledKernel)
Section titled “ TryGetOwned(string, out InstalledKernel)”Atomically fetches the kernel currently registered under pluginId AND verifies this
session owns it, returning that exact instance. Use this instead of a separate DotBoxD.Plugins.PluginSession.Owns(System.String) + registry
lookup so authorization binds to the kernel actually returned — there is no window in which a same-id
hot-replace could swap a different kernel in between the check and the fetch.
public bool TryGetOwned(string pluginId, out InstalledKernel kernel)Parameters
Section titled “Parameters”pluginId string
kernel InstalledKernel
Returns
Section titled “Returns”Uninstall(string)
Section titled “ Uninstall(string)”public bool Uninstall(string pluginId)Parameters
Section titled “Parameters”pluginId string
Returns
Section titled “Returns”UpdateSettingsAsync(string, IReadOnlyDictionary<string, object?>, bool, CancellationToken)
Section titled “ UpdateSettingsAsync(string, IReadOnlyDictionary<string, object?>, bool, CancellationToken)”Updates live settings for a kernel this session owns. Rejects ids the session does not own so one plugin cannot tune another plugin’s kernel.
public ValueTask UpdateSettingsAsync(string pluginId, IReadOnlyDictionary<string, object?> values, bool atomic = false, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”pluginId string
values IReadOnlyDictionary<string, object?>
atomic bool
cancellationToken CancellationToken