fleet: require a minimum version of the peer at the handshake [CI]
MoShiro__MinAgentVersion makes the backend refuse agents below it at hello (fleet_version_required); fleet.min_server_version or MOSHIRO_MIN_SERVER_VERSION makes the agent drop a backend below it. Either side waits five seconds and shakes hands again, because the other one may be updating.
This commit is contained in:
1 parent
fb3a9c260f
commit
5822285a88
16 files changed
+266
-7
No files matched your search
@@ -52,6 +52,9 @@ public sealed class FleetLinkOptions
|
||||
|
||||
public string NodeVersion { get; init; } = "0.0.0";
|
||||
|
||||
/// <summary>服务端至少要是哪个版本(每次握手重新取);空表示不要求。不够就关掉这条连接,等 <see cref="VersionRetry"/> 再握手,服务端可能正在更新。</summary>
|
||||
public Func<string?>? MinServerVersion { get; init; }
|
||||
|
||||
/// <summary>框架之外的能力,例如 <c>moshiro.v1</c> 与 <c>moshiro.kinds:udp_echo,tcp_echo</c>。</summary>
|
||||
public IReadOnlyList<string> Capabilities { get; init; } = [];
|
||||
|
||||
@@ -100,7 +103,11 @@ public sealed class FleetLink
|
||||
private volatile RpcSession<LinkContext>? _session;
|
||||
private volatile bool _stopped;
|
||||
|
||||
/// <summary>版本不够时重新握手的间隔:固定,不退避(对方更新完马上就能连上)。</summary>
|
||||
public static readonly TimeSpan VersionRetry = TimeSpan.FromSeconds(5);
|
||||
|
||||
private static readonly TimeSpan s_tcpTimeout = TimeSpan.FromSeconds(4);
|
||||
private TimeSpan? _fixedRetry;
|
||||
private int _failedConnects;
|
||||
|
||||
public FleetLink(FleetLinkOptions options, RpcRouter<LinkContext> router, IEnumerable<IStateHandler> handlers, Outbox outbox, TimeProvider time, INodeLog log)
|
||||
@@ -166,7 +173,8 @@ public sealed class FleetLink
|
||||
return;
|
||||
}
|
||||
|
||||
TimeSpan delay = _options.Backoff.Next();
|
||||
TimeSpan delay = _fixedRetry ?? _options.Backoff.Next();
|
||||
_fixedRetry = null;
|
||||
_log.Warn("link down, retrying", ("err", reason), ("retry_ms", (long)delay.TotalMilliseconds));
|
||||
await Task.Delay(delay, _time, ct);
|
||||
}
|
||||
@@ -263,7 +271,19 @@ public sealed class FleetLink
|
||||
Result<HelloResult> helloResult = await session.RequestAsync(FleetMethods.Hello, hello, FleetRpcContext.Default.HelloParams, FleetRpcContext.Default.HelloResult, ct);
|
||||
if (!helloResult.IsSuccess)
|
||||
{
|
||||
return "hello failed: " + helloResult.Error.Code;
|
||||
if (helloResult.Error.Code == FleetErrors.VersionRequired)
|
||||
{
|
||||
_fixedRetry = VersionRetry; // 我们的版本低于服务端要求的:等自己更新,每 5 秒再试一次
|
||||
}
|
||||
|
||||
return "hello failed: " + helloResult.Error.Code + (_fixedRetry is null ? "" : ": " + helloResult.Error.Message);
|
||||
}
|
||||
|
||||
string? requiredServer = _options.MinServerVersion?.Invoke();
|
||||
if (NodeVersions.IsBelow(helloResult.Value.ServerVersion, requiredServer))
|
||||
{
|
||||
_fixedRetry = VersionRetry; // 服务端版本低于我们要求的(它可能正在更新):不发任何东西,5 秒后重新握手
|
||||
return $"server version {helloResult.Value.ServerVersion} is below the required {requiredServer}";
|
||||
}
|
||||
|
||||
Outbox.ResetSent();
|
||||
|
||||
Reference in new issue
Block a user