Repository navigation
[Runtime Configuration] 动态配置 / Hot Reload 长期跟踪 #262
Description
Use case
SharpLink 当前在 dev 分支已经形成比较清晰的 Build/Compile/Materialize 与 immutable runtime snapshot 架构,并且动态模块已经使用 generation、atomic publication 与 drain 等模式解决运行时注册/替换问题。
下一步希望逐步支持 Runtime Dynamic Configuration / Hot Reload:允许部分 Client / Server 运行时策略在实例已经启动后启用、禁用或更新,同时继续保护现有热路径,不把 Builder 阶段的可变 options 直接暴露成长期 mutable runtime state。
本 issue 作为长期总跟踪,不承载各模块的完整实现讨论。具体语义、API、状态迁移和 benchmark 在独立子 issue 中完成。
分析与实施基线:dev。
相关架构背景:#67 已确立 immutable snapshot、单一 ownership、保护热路径、动态 generation/drain 等长期原则;本跟踪在这些原则之上扩展 runtime configuration,而不是重新放开已经冻结的 RuntimeContext / BuildPlan。
总体目标
Builder / Compile
↓
建立初始 immutable configuration
↓
Client / Server running
↓
control path 构造并验证新的 subsystem generation
↓
atomic publication
↓
新 logical operation 使用新 generation
旧 operation 保持 generation consistency / 必要时 drain
核心目标不是“让所有 Options 都 mutable”,而是把当前“一次 Build 后整个生命周期固定”的 freeze 细化为:
不同 subsystem 拥有各自 immutable generation,并根据语义决定 next-call、next-attempt、next-message、new-session 或 lifecycle-loop 生效。
通用工程原则
- 不破坏 Compile / Materialize。 Builder 仍负责构造初始合法状态;动态配置是运行时 control plane,不把 mutable builder options 直接泄漏到 hot path。
- Immutable candidate + validate + atomic publish。 更新必须先完整构造候选配置、验证成功,再一次发布;运行时不得观察到半更新状态。
- 按 subsystem 分 generation。 不引入一个所有 RPC 都读取的巨型
DynamicRuntimeOptions;Call Policy、Interceptors、Admission、Compression、Session Configuration、Lifecycle Configuration 等应按热路径和语义拆分。 - 每个 logical operation 最多 capture 一次相关 generation。 一个 RPC、attempt、stream/session 生命周期内不得混用更新前后的 generation。
- 关闭功能必须保留 fast path。 disabled state 优先使用
null/ empty immutable snapshot + predictable branch,不使用需要额外虚调用或 allocation 的 no-op runtime object。 - 不在 request path 引入全局锁。 更新可以在 control path 加锁、构建、解析和校验;请求路径继续使用 atomic/volatile publication、immutable lookup 与现有无锁/细粒度状态。
- Stateful subsystem 必须分离 policy 与 state。 Admission、Circuit Breaker、Endpoint Admission、Rate Limiter 等不能简单 new controller 后替换,否则 active permit、token/window、attempt token 等状态可能失真。
- 旧 generation 的资源有明确生命周期。 如果 generation 持有 lease、limiter、timer、partition state 或其他资源,替换后必须有 retire/drain/reclaim 语义;不能在仍有 in-flight operation 时直接 Dispose。
- Session / handshake-sensitive 配置不强行即时生效。 会影响 wire negotiation、buffer/table sizing、compression profile、authentication 等配置默认采用 new-session semantics,除非独立设计证明可以安全 renegotiate。
- 动态更新不应隐式中断现有业务调用。 降低 concurrency/queue limit 时默认不杀死已经持有 permit 或已经排队的调用,而是限制后续 admission;需要强制取消的行为必须另有显式语义。
- 性能变化必须可测。 触及 unary / streaming invocation hot path 的模块必须提交启用、关闭、更新前后的 BenchmarkDotNet 对比,并关注 allocation、吞吐与 p99。
- 不在总 issue 锁死公共 API。 本 issue 约束 runtime model 和生效语义;
UpdateXxx(...)、control handle、hosting integration 等具体 API 在子 issue 讨论。
Dynamic semantics 分类
| 分类 | 典型模块 | 预期生效点 |
|---|---|---|
| Next logical call | Interceptors、default timeout、retry、exception mapping | 下一次 RPC capture 新 snapshot |
| Next attempt | Client Endpoint Admission / Circuit Breaker、Load Balancing | 下一次 endpoint attempt |
| Next message/call policy | Compression thresholds 等本地策略 | 下一次相关 encode/call |
| Active control loop / next batch | RPC flush/batching | 现有 send pump 下一次 batching decision |
| Stateful live update | Server Admission、global concurrency、部分 pool policy | 保留 runtime state 后更新 policy |
| Lifecycle/control loop | Heartbeat、部分 pool sizing、reconnect policy | timer/supervisor loop 接收新 snapshot |
| New session only | Protocol limits、flow-control windows、compression provider/WireProfile、authentication | 新连接/新 session |
| Rolling replacement | Transport、listener/TLS topology、service graph root 等资源拓扑 | 新 generation 建立后排空旧资源 |
统一 publication 模型
默认模式:
old immutable snapshot / program
↓
control path
↓
clone / build candidate
resolve ids / compile route if needed
validate completely
reconcile reusable runtime state
↓
atomic publish
↓
new operations capture new generation
old operations keep old generation
↓
retire/drain old resource generation when required
禁止的默认模式:
server.Options.Xxx.Value = ...;多字段配置不得通过逐字段 mutable write 更新,否则无法保证一致性、验证失败回滚和 logical-operation generation consistency。
性能要求
Disabled path
- 不产生 per-call allocation。
- 不调用 no-op controller / interceptor pipeline。
- 不引入 lock。
- 理想情况下仅增加必要的 snapshot/pointer load + predictable branch;如果某 subsystem 可以完全位于 lifecycle/new-session 路径,则普通 RPC hot path 不应新增任何工作。
Enabled path
- immutable routing / precompiled execution plan 优先。
- 同步成功路径不应为了支持动态配置额外分配对象。
- 只有真实 queue / async wait / contention 才进入较重的状态对象路径。
Update path
- 可以执行 allocation、validation、dictionary/frozen snapshot 构造和状态 reconciliation。
- publication 必须短且原子,不阻塞正在运行的 RPC。
- 更新频率不以 request-rate 为尺度设计;dynamic configuration 属于 control-plane operation。
Stateful subsystem 约束
对 stateful subsystem,默认采用:
Immutable Program / Policy
+
Reusable Runtime State
例如 Admission:
AdmissionProgram generation N
├─ Global rule ─────┐
├─ Contract rule ────┼──> AdmissionState objects
└─ Method rule ──────┘
update
AdmissionProgram generation N+1
├─ unchanged rules -> reuse compatible state
├─ resized rules -> update/reconcile state
├─ new rules -> create state
└─ removed/structurally changed rules -> retire/drain generation
这样可以避免配置替换时重置 active permit、token bucket/window、breaker state 等真实运行状态。
初始模块清单
下面每一项后续单独建立 issue,并回链本 tracking issue。
-
Dynamic Interceptors
- Client / Server interceptor immutable pipeline snapshot
- runtime enable / disable / replace
- 一个 logical RPC 只 capture 一次 pipeline generation
- 保留 zero-interceptor direct fast path
- benchmark disabled / enabled / update cases
-
Dynamic Server Admission Control
- runtime enable / disable
AdmissionProgram与 runtime admission state 分离- dynamic concurrency resize
- queue policy update
- token bucket / fixed window / sliding window 的 state-preserving update semantics
- partition generation / selector replacement
- retire / drain semantics 与 benchmark
-
Dynamic Client Endpoint Admission / Circuit Breaker
- policy generation replacement
TryAcquire与Report必须绑定同一 policy generation- outstanding attempt token / lease 的 retire-drain
- circuit-breaker state preservation / reset semantics
-
Dynamic Call Policy
- client default request timeout
- retry plan / retry policy
- server exception mapper 等 next-call policy
- 明确一个 call capture 一次 policy snapshot
-
Dynamic Compression Policy
MinimumPayloadBytesMinimumSavingsBytesMinimumSavingsRatio- 本地 encode policy 与 wire/session negotiation 分离
- provider / WireProfile 保持 new-session semantics
-
Dynamic RPC Flush / Batching Policy — [Runtime Configuration][Session] Dynamic RPC flush and batching policy #590
FlushSizeThresholdMaxLatency- 现有 active Client/Server session 的 send pump 直接采用新策略
- lowering threshold / latency 时可 prompt wake/re-evaluate
- 不创建第二 send pump / timer lifecycle
- 不改变 Protocol v2、flow-control 或 handshake/session invariant
-
Dynamic Lifecycle Configuration
- heartbeat interval / timeout — [Runtime Configuration][Client] Dynamic heartbeat interval and liveness timeout #586
- connection pool sizing / graceful scale-down — [Runtime Configuration][Client] Dynamic connection-pool scaling and graceful scale-down #587
- reconnect backoff/jitter 等 lifecycle policy 后续按独立 issue 收口
- 优先通过 control loop/timer 重调度,不污染 RPC invocation path
-
Dynamic Telemetry Detail / Enrichment Policy — [Runtime Configuration][Telemetry] Dynamic telemetry detail and enrichment policy #589
- expensive / high-cardinality tags 与 enrichment
- optional diagnostic events
- next-call / next-event semantics
- sampling/exporter/provider lifecycle 保持 OpenTelemetry / Hosting ownership
-
Dynamic Session Configuration — [Runtime Configuration][Session] Audit session configuration disposition and new-session semantics #588
- protocol limits
- receive / connection flow-control windows
- pending request / stream capacities
- compression provider profile
- authentication / handshake-sensitive configuration
- 明确哪些仅作用于 new session,哪些未来可能支持 renegotiation
-
Runtime Configuration Control Surface / Hosting Integration
- 在前述模块语义稳定后再统一评估公共 API
- standalone Client/Server control surface
- Hosting / OptionsMonitor 等集成是否需要独立 package/API
- 不为了 API 统一把无关 subsystem 强行合并成一个 runtime options object
建议实施顺序
第一批先覆盖两种最典型的动态模型:
- Dynamic Interceptors — 代表纯 immutable snapshot / next-call 动态化。
- Dynamic Server Admission Control — 代表 immutable program + stateful runtime state 动态化。
这两个模块稳定后,再将相同 generation / publication / drain 模式复用于其他模块。
随后建议:
- Dynamic Call Policy
- Dynamic Client Endpoint Admission / Circuit Breaker
- Dynamic Compression Policy
- Dynamic Lifecycle Configuration
- Dynamic RPC Flush / Batching Policy
- Dynamic Telemetry Detail / Enrichment Policy
- Dynamic Session Configuration
- 统一 Runtime Configuration Control Surface / Hosting Integration
测试与验证门禁
每个子 issue 按影响范围至少覆盖:
- concurrent configuration update + RPC stress;
- update 与 Stop/Dispose/Drain 并发;
- in-flight logical operation generation consistency;
- invalid candidate 不得改变当前已发布配置;
- repeated enable/disable/update 不得泄漏 resource / task / limiter / lease;
- fake-time 测试适用于 timer/rate/retry/heartbeat/flush 等时间相关模块;
- dynamic module / ALC 场景不得因为旧 generation 保留不必要 assembly owner;
- NativeAOT / trimming 受影响模块继续满足当前约束。
触及 RPC hot path 的子 issue 必须附 BenchmarkDotNet 前后数据:
- disabled baseline;
- enabled baseline;
- steady state after update;
- allocation / throughput / latency;
- 不得因为“支持动态配置”在未启用功能时引入明显锁竞争或无依据 allocation。
Compatibility
- Protocol v2 wire format 默认保持不变。
- Contract / Method / DTO schema identity 默认保持不变。
- Dynamic configuration 不自动等于 wire renegotiation。
- 对 new-session-only 配置,已有 session 保持其 immutable negotiated snapshot,直到自然关闭或显式连接生命周期策略处理。
- CLR/source API 可以在当前 breaking architecture 收敛阶段按项目策略调整,但不通过大量 compatibility shim 掩盖错误的 runtime model。
Out of scope
本 tracking issue 不直接实现以下内容:
- 不把所有 RuntimeOptions 改成 thread-safe mutable object。
- 不要求所有配置都能够即时动态生效。
- 不为了 hot reload 强行支持现有 session 的 protocol renegotiation。
- 不在这里决定最终统一
UpdateRuntimeOptions/IOptionsMonitor等 public API。 - 不把 Transport / TLS listener / service-provider root 等资源拓扑当成普通 atomic field 修改;需要时采用 generation + rolling replacement 独立设计。
- 不在一个 PR 中实现所有模块。
总完成定义
- 所有计划支持动态更新的 subsystem 都有明确的生效点:next-call / next-attempt / lifecycle / active-control-loop / new-session / rolling replacement。
- 所有模块更新都采用完整 candidate validation + atomic publication,不存在半更新状态。
- 所有 stateful subsystem 都定义 state preservation / reset / drain 语义。
- 所有 logical operation 都能证明不会混用两个 configuration generation。
- disabled feature 保持无 allocation、无 request-path lock,并有 benchmark 证明性能回退处于噪声范围或有明确理由。
- session-sensitive 配置不会静默改变已协商 session 的 wire/runtime invariant。
- update 与 stop/dispose/drain/动态模块卸载之间有竞态测试。
- public control surface 在各模块模型稳定后统一审计,不反向绑死底层实现。
- 文档明确列出哪些配置支持 runtime update、何时生效、旧 operation/session 如何处理。
Checks
- 以
dev为当前分析与实施基线。 - 已检查现有 open issue,未发现同一 Runtime Dynamic Configuration / Hot Reload 长期跟踪 issue。
- 本 issue 只建立共同 runtime model、性能约束与模块拆分,不提前锁死具体公共 API。
Activity
SunSi12138 commentedon Aug 20, 2026
首批两个实施子 issue 已建立:
后续模块应优先复用这两个 issue 验证后的 publication / generation / lifecycle 模式。
SunSi12138 commentedon Aug 21, 2026
Progress update: Dynamic Interceptors is complete.
devas866dd7557b14a4593cde0f4f3df263720ea9f943.devand the resulting head passed PR Quick fix(generator): allocate arrays after generic element ranks (#873) #881 and CodeQL [P3][3.0][Generator] 服务 required 成员未纳入构造校验,生成 activator 才报 CS9035 #878.SunSi12138 commentedon Aug 22, 2026
新增跨模块基础架构跟踪 #273:统一请求资源准入、两阶段 Call Reservation 与 Decode Execution。
它与本总跟踪的关系是:#262 继续定义 runtime dynamic configuration 的 generation / atomic publication / retire-drain 原则;#273 则提供 Server request hot path 的稳定资源内核,使
call reservation / decode concurrency / retained/decoded bytes / stream budget不依赖某个动态 policy generation 的存在。对 Dynamic Server Admission #264 尤其重要:未来
AdmissionProgramenable/disable/replace 只改变 policy 层,不再决定 compressed Request 是 eager decode 还是 deferred decode。基础ResourceGovernorsafety invariant 在 Admission disabled 时也始终存在。#273 还把 compression execution model(inline incremental / cooperative quantum / bounded persistent DecodeExecutor / optional genuine async provider capability)纳入 Phase 0 数据验证,避免为了动态化或安全性把 per-request ThreadPool handoff 固化成长期热路径成本。
SunSi12138 commentedon Aug 27, 2026
Tracker update — Dynamic Server Admission Control completed (2026-08-27)
The Dynamic Server Admission Control workstream tracked by #264 is complete and #264 is now closed.
Final integrated implementation on
dev:dev:ebaabca30153822d949da32b3c7674d4a8341d80Final #336 exact-head validation: PR Quick
33038771499, CodeQL33038771343, Padding33038771236; 1,947/1,947 primary managed tests passed plus NativeAOT/package/load/chaos gates.This completes the tracker item for Dynamic Server Admission Control and validates the intended
immutable program + stable stateful runtime kernel + atomic publication + retire/drain/reclaimpattern.Leaving #262 open for the remaining runtime-configuration workstreams (Dynamic Interceptors, client endpoint admission/circuit breaker, call policy, compression policy, lifecycle/session configuration, and the eventual broader control-surface/hosting integration).
SunSi12138 commentedon Sep 5, 2026
Housekeeping status — 2026-09-06
Dynamic Server Admission (#264) has completed its implementation stack and is closed. That removes one major item from this long-term runtime-configuration tracker.
This tracker remains open because it still owns broader runtime-configuration follow-up areas that are not completed as a whole, including Client endpoint-admission/circuit-breaker dynamics, call-policy updates, compression policy/session-generation updates, lifecycle/session configuration, and the eventual unified control/Hosting surface.
Treat #264 as completed history; do not reimplement its old phases from this parent body. New work should use current
devand focused leaf issues.SunSi12138 commentedon Sep 6, 2026
Status refresh — 2026-09-06
Current baseline:
dev@51e3f2c66a24615abf738f76a2380f223d72f2ab.The original tracker defined 8 top-level Runtime Dynamic Configuration workstreams. Re-checking current
dev, merged/closed implementation issues, and the remaining open backlog gives this status:Completed
Post-completion simplification work such as #410 does not reopen #264; it may simplify the implementation/semantics further, but the runtime-configuration capability itself is already implemented.
Related foundations completed, but not a completed #262 workstream
Timeout -> RpcDeadline -> TimeBudget -> DeadlineExceededlifetime model and removed the old contract-levelSharpLinkCallOptionsshape. This is a strong foundation for Dynamic Call Policy, but it does not itself add runtime call-policy publication/update.Remaining top-level workstreams
Dynamic Call Policy
Dynamic Client Endpoint Admission / Circuit Breaker
TryAcquire/Reportbound to one attempt-policy generation;Dynamic Compression Policy
MinimumPayloadBytes,MinimumSavingsBytes,MinimumSavingsRatioor their final equivalents);Dynamic Lifecycle Configuration
Dynamic Session Configuration
Runtime Configuration Control Surface / Hosting Integration
IOptionsMonitorintegration are justified;RuntimeOptionsobject or force unrelated subsystems through one update transaction.Progress
By top-level workstream count:
That is 25% complete / 75% remaining by item count, but item count overstates the remaining engineering effort because #264 Dynamic Server Admission was by far one of the largest and highest-state-space workstreams in the tracker.
A more useful planning view is:
Recommended continuation order
Call Policy and Client Endpoint Admission can be characterized in parallel because their final generation scopes differ (
logical callvsattempt), but implementation should avoid introducing a shared generic configuration framework merely for uniformity.Compression should incorporate the final #430 ownership decision before locking a public runtime-update surface. Session-sensitive provider/profile changes should remain new-session-only unless separately proven safe.
Tracker close condition
#262 should remain open. It is ready to close only after the six remaining workstreams each have an explicit disposition (
implemented,No-Go/not supported dynamically, or intentionally superseded) and the final control-surface/Hosting audit is complete.SunSi12138 commentedon Sep 6, 2026
Dynamic Compression Policy 子 issue 已拆出:#550
最终边界:
实现/测试/wire capability/benchmark 细节集中在 #550。
SunSi12138 commentedon Sep 6, 2026
Dynamic Compression Policy 已在 #550 进一步收敛,建议总跟踪按 #550 的最终语义理解,而不再仅视为三个 threshold 的 hot reload:
Providers / WireProfile保持 build-time immutable capability;具体并发、ACK/coalescing、handshake initial preference 与性能约束以 #550 为准。Protocol/minor/version bump 不在该子 issue 中决定,留到 2.0 相对 1.1 的发布边界统一处理。
SunSi12138 commentedon Sep 7, 2026
Dynamic Compression Policy 已完成落地并回收子 issue:
cc8f2e38ed8e2fd3a86cafbb68f2f71ad4d34407最终边界与本 tracking issue 的长期原则一致,但比最初条目进一步收敛:
SharpLinkCompressionOptions不再保存 send threshold authority;#550 已按 completed 关闭。#262 继续作为其他 Runtime Configuration 子系统的长期总跟踪。
SunSi12138 commentedon Sep 7, 2026
Dynamic Call Policy 已按最终讨论拆成两个独立 Client 全局策略子 issue:
两者保持独立 publication,不再强制合并成一个巨型 CallPolicy snapshot。现有 method timeout/idempotency、per-call cancellation、Endpoint Admission/Circuit Breaker、session/lifecycle 配置均不纳入这两个 leaf。
SunSi12138 commentedon Sep 7, 2026
Dynamic Client Endpoint Admission / Circuit Breaker 已按已确认边界拆成两个独立子 issue:
TryAcquire时的 policy + token,并由同一 policyReport。MinimumThroughput、FailureRatio、SamplingDuration、BreakDuration、HalfOpenMaxCalls五个现有参数的热更新,并固定 Closed/Open/HalfOpen 状态迁移语义。两者继续互斥,不在本轮重构 endpoint-cluster / multi-cluster ownership。
SunSi12138 commentedon Sep 7, 2026
第三部分(Dynamic Lifecycle Configuration)已按职责拆为两个独立子项:
两项均保持 #262 的 complete-candidate validation、atomic/control-path publication、Stop/Dispose race safety 与 zero per-RPC lock/allocation 原则。
SunSi12138 commentedon Sep 7, 2026
Additional runtime-configuration child tracking:
[Runtime Configuration][Client] Dynamic endpoint selection and load-balancing policy #591 — Dynamic endpoint selection and load-balancing policy
PowerOfTwoChoices/Random/RoundRobin/LeastPendingISharpLinkEndpointSelector[Runtime Configuration][Client] Complete and dynamically update reconnect policy #592 — Complete and dynamically update reconnect policy
InitialDelay/MaxDelay/BackoffFactor/ jitter / stable-reset duration[Runtime Configuration][Session] Audit session configuration disposition and new-session semantics #588 now also tracks the focused Server pre-session connection-admission limit runtime update using the existing [server][admission] Bound accepted connections and concurrent handshakes #162 infrastructure:
These remain separate from #587 Client connection-pool sizing: #587 controls how many outbound connections one Client maintains, while #588/#162 connection admission controls the Server-wide accepted/pre-auth resource envelope.
SunSi12138 commentedon Sep 8, 2026
Tracker addition — Dynamic Server Call Capacity
#588 的 Session/pre-session audit 暴露出一个相邻但独立的 runtime-config domain:Server RPC call capacity。
当前已有两层 build-time hard bound:
其中
MaxConcurrentCallsPerServer是整个 Server 实例的全局 active RPC 上限,MaxConcurrentCallsPerConnection是单物理连接 active RPC 上限。它们保护的是已经建立 Session 之后、业务 RPC invocation 之前的 call-capacity domain;不属于 #588 的 negotiated Session configuration,也不属于 #162/#588 的 pre-session connection/handshake admission。已建立独立实施 issue:#611。
建议在 #262 roadmap 中将其视为独立的 Dynamic Server Call Capacity 子模块,而不是并入 Dynamic Session Configuration 或 Dynamic Server Admission Control:
MaxConcurrentCallsPerConnection;MaxConcurrentCallsPerServer;ServerCallAdmission/ per-connection active-call accounting,不通过 fresh controller/counter replacement 分裂容量域;建议 dynamic-semantics 分类补充为:
建议后续实施顺序在 Dynamic Server Admission Control 之后增加 Dynamic Server Call Capacity,并把历史 #45 作为 build-time configurability / capacity evidence 的背景,而不是把 #45 已完成的“可配置”误认为已经具备 runtime resize。
这项不扩大 #588:#588 继续只负责 Session disposition + pre-session connection/handshake target update。
SunSi12138 commentedon Sep 9, 2026
Runtime Configuration 子项 #611(per-connection / server-wide active RPC hard limits 的运行时 resize)已由 #643 完成并合入
dev,squash SHAe464b4483d74760733af46fe012d148779024be2;#611 已按 completed 关闭。该子项采用独立 immutable capacity snapshot + 现有 authoritative active-call accounting:多字段完整校验后原子发布,增长作用于后续 acquisition,缩容不抢占已有调用,Stop/drain 封口更新;未把 hard call capacity 折叠进 Dynamic Admission。Exact-head Fast/Quick/CodeQL/Extended 均通过。
SunSi12138 commentedon Sep 10, 2026
Final tracker audit — 2026-09-10
Re-checked the current
devruntime-configuration surface and the work that landed after the 2026-09-06 status refresh. The old2 / 8progress comment is now stale: the planned high-value runtime-configuration domains have either been implemented or have an explicit non-live-update disposition.Implemented / completed dynamic domains
The tracker has now produced the following completed work:
Together these cover the useful runtime semantics originally intended by this tracker:
The implementations consistently converged on the intended pattern: complete candidate validation, immutable/current policy publication, stable state where needed, explicit retire/drain/reclaim, and no giant mutable runtime-options object.
Final audit of possible additional dynamic candidates
I also re-audited remaining build-time knobs before closing this tracker. None currently justifies extending #262 with another mandatory workstream.
Server heartbeat interval / peer-liveness timeout — defer / not part of this tracker
Server still has build-time heartbeat check/timeout configuration, while #586 intentionally implemented the Client side.
Technically this could be made into another lifecycle/control-loop update. However there is no demonstrated operational requirement strong enough to justify another public runtime mutation surface now, and Server lifecycle ownership is being clarified separately in #646.
Keep Server heartbeat build-time for now. If a concrete operational use case appears after #646, open a focused Server-heartbeat runtime issue with explicit rescheduling/Stop race semantics rather than reopening this general tracker.
MinReadyEndpoints/ readiness thresholds — defer to lifecycle/readiness modelThese are currently topology/readiness configuration, not a general runtime-options concern. #644 is explicitly separating Client lifecycle from cluster connectivity/readiness, so adding a hot-update API before that model settles would prematurely lock in semantics.
If runtime readiness-policy changes are still useful after #644, track them as a focused readiness-policy issue. They are not a blocker for #262 completion.
Connect / handshake / readiness timeout knobs — keep build/new-attempt scoped
There is no compelling reason to make every connection-establishment timeout independently hot mutable. Their ownership and startup/readiness semantics are also affected by #644/#646.
Keep them at their current construction/new-attempt boundaries unless a concrete production use case justifies a narrow future issue.
Server
IRpcExceptionMapperreplacement — no framework hot-replacement API requiredIRpcExceptionMapperremains an application-provided, instance-scoped object configured at build time. If an application needs policy changes inside its mapper, the mapper itself can own an immutable/application configuration snapshot. SharpLink does not need another framework-level generation/replacement API solely to swap that object.This is therefore an explicit No-Go for the current tracker rather than an unfinished Dynamic Call Policy item.
Protocol / flow-control / pending / stream / compression provider / authentication state — new-session-only by design
#588 completed the disposition audit. Negotiated or structurally session-scoped state must not silently mutate underneath an active
RpcSession. CompressionProvider / WireProfilefollows the same boundary established by #550.No general active-session renegotiation feature is justified.
ResourceGovernor / decode-memory safety budgets — keep as hard resource configuration unless a real resize use case appears
#273 established the stable resource-safety kernel. The fact that a hard resource bound is configurable does not automatically mean it should become live-resizable. Runtime shrink/grow would require its own accounting and non-preemption proof similar to #611.
There is currently no concrete missing operational capability that warrants extending #262 for these bounds.
Transport / TLS listener / certificate topology / service graph root — rolling replacement, not ordinary hot reload
These remain resource-topology changes. If a real certificate/listener/transport rolling-rotation use case needs framework support, it should be designed as a focused generation + rolling-replacement feature with explicit ownership and drain semantics, not exposed through a generic mutable runtime-options surface.
Final control-surface / Hosting disposition
The final control-surface audit is also a No-Go for one unified mutable runtime configuration object.
The completed subsystems deliberately have different publication boundaries and state semantics:
Forcing these through one
UpdateRuntimeOptions(...)transaction or one automatically-appliedIOptionsMonitor<T>graph would blur ownership, validation, rollback, generation capture and failure reporting.The canonical model should therefore remain narrow subsystem-specific runtime control APIs. Applications using Generic Host may bridge their own
IOptionsMonitor/configuration source to those explicit APIs when useful. A future optional Hosting adapter can be added only if real repeated application code demonstrates value; it is not required as part of the runtime architecture.Relationship to #644 / #646
#644 and #646 redesign the public Client/Server lifecycle model (
StartAsync / WaitForShutdownAsync / StopAsync). They may require existing runtime-control APIs/docs to be adapted to the new lifecycle boundaries, but they do not expose an unfinished #262 dynamic-configuration workstream.If those lifecycle changes reveal a genuinely new runtime policy that should be mutable, it should get a focused issue with its own semantics instead of keeping this broad tracker permanently open.
Closure
No additional runtime-dynamic feature is currently strong enough to justify extending this long-running tracker.
The main architectural goal is satisfied:
Closing #262 as completed. Future dynamic-configuration requests should be narrow, use-case-driven issues rather than additions to a permanently open umbrella tracker.