Skip to content

[Runtime Configuration][Client] Dynamic global request-timeout policy #578

Closed

Description

@SunSi12138

Parent tracker: #262
Related lifetime/deadline foundation: #287

Goal

Allow one running ISharpLinkClient instance to update its client-wide default request-timeout fallback without rebuilding or replacing the Client.

This is intentionally a narrow next-logical-call policy. It does not make method metadata, caller cancellation, connection/handshake timeouts, or session limits dynamically mutable.

Runtime semantics

Support a client-wide timeout policy with three states:

Recommended/default timeout
Custom timeout
Disabled

An update affects only logical RPCs that start after publication:

Call A starts under timeout generation N
runtime update publishes generation N+1
Call A keeps its already-resolved deadline
Call B starts under generation N+1

The existing method timeout precedence remains unchanged:

explicit method [Timeout(value)]
    > client-wide fallback

parameterless method timeout policy
    may use the client-wide fallback according to current semantics

A runtime update must not rewrite an already-created RpcDeadline or extend/shorten an in-flight logical call.

Scope

  • runtime enable/set of the client-wide default timeout;
  • runtime disable of the client-wide default timeout;
  • update to a new positive timeout value;
  • full candidate validation before publication;
  • atomic publication with next-logical-call visibility;
  • in-flight call generation consistency;
  • update vs Stop/Dispose race semantics;
  • no new per-call allocation or request-path lock;
  • diagnostics/docs expose the effective current client-wide timeout policy where appropriate.

Explicitly out of scope

  • dynamic mutation of method [Timeout] metadata;
  • caller CancellationToken or per-call options;
  • per-attempt timeout;
  • connect/handshake/readiness timeout;
  • heartbeat/lifecycle timeout;
  • server-side timeout policy;
  • retry policy implementation (tracked separately under [Runtime Configuration] 动态配置 / Hot Reload 长期跟踪 #262);
  • active-call deadline renegotiation.

Correctness invariants

  1. A logical call resolves the effective timeout/deadline once at its invocation boundary.
  2. Runtime update cannot alter an already-resolved RpcDeadline.
  3. Invalid updates are rejected before publication and leave the current policy unchanged.
  4. Disabled timeout means no client-wide fallback; existing method/inherited/caller lifetime semantics remain authoritative.
  5. DeadlineExceeded remains the terminal outcome once the logical-call deadline wins.
  6. Stop/Dispose prevents or deterministically rejects further policy publication according to the established dynamic-config lifecycle pattern.
  7. No request-path global lock, timer-per-policy, or per-call policy allocation is introduced.

Validation

At minimum cover:

  • enabled -> new duration;
  • enabled -> disabled;
  • disabled -> enabled;
  • invalid duration rollback;
  • update while an old call is in flight;
  • update immediately before/after a new call starts;
  • method timeout precedence;
  • inherited time budget behavior;
  • caller cancellation remains independent;
  • concurrent repeated updates;
  • update vs Stop/Dispose;
  • tiny unary hot-path allocation/performance before/after.

Completion

This issue is complete when a running Client can atomically replace only its global request-timeout fallback, with existing calls retaining their captured deadline and new calls observing the new policy.

Activity

  1. SunSi12138 commented on Sep 7, 2026

    @SunSi12138
    OwnerAuthor

    Implemented and reviewed in #593, now squash-merged into dev as d03ef7ed0ab3f9171178f8fde0c2b36ba1b6efd5. Runtime request-timeout updates preserve per-logical-call generation semantics, lifecycle rejection, and the no-lock hot path; PR Fast, Extended, and CodeQL are green. Closing as completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions