public static async Task <TcpConnectionHeaderMessage.SupportedFeatures> NegotiateProtocolVersionAsync(JsonOperationContext documentsContext, Stream stream, TcpNegotiateParamaters parameters) { using (var writer = new BlittableJsonTextWriter(documentsContext, stream)) { var currentVersion = parameters.Version; while (true) { if (parameters.CancellationToken.IsCancellationRequested) { throw new OperationCanceledException($"Stoped Tcp negotiation for {parameters.Operation} because of cancelation request"); } documentsContext.Write(writer, new DynamicJsonValue { [nameof(TcpConnectionHeaderMessage.DatabaseName)] = parameters.Database, // _parent.Database.Name, [nameof(TcpConnectionHeaderMessage.Operation)] = parameters.Operation.ToString(), [nameof(TcpConnectionHeaderMessage.SourceNodeTag)] = parameters.NodeTag, [nameof(TcpConnectionHeaderMessage.OperationVersion)] = currentVersion }); writer.Flush(); int version; if (parameters.ReadResponseAndGetVersionAsync == null) { version = parameters.ReadResponseAndGetVersion(documentsContext, writer, stream, parameters.Url); } else { version = await parameters.ReadResponseAndGetVersionAsync(documentsContext, writer, stream, parameters.Url, parameters.CancellationToken).ConfigureAwait(false); } //In this case we usally throw internaly but for completeness we better handle it if (version == -2) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(TcpConnectionHeaderMessage.OperationTypes.Drop, TcpConnectionHeaderMessage.DropBaseLine40000)); } var(supported, prevSupported) = TcpConnectionHeaderMessage.OperationVersionSupported(parameters.Operation, version); if (supported) { //We are done if (currentVersion == version) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(parameters.Operation, version)); } //Here we support the requested version but need to inform the otherside we agree currentVersion = version; continue; } if (prevSupported == -1) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(TcpConnectionHeaderMessage.OperationTypes.None, TcpConnectionHeaderMessage.NoneBaseLine40000)); } currentVersion = prevSupported; } } }
public static TcpConnectionHeaderMessage.SupportedFeatures NegotiateProtocolVersion(JsonOperationContext context, Stream stream, TcpNegotiateParameters parameters) { if (Log.IsInfoEnabled) { Log.Info($"Start negotiation for {parameters.Operation} operation with {parameters.DestinationNodeTag ?? parameters.DestinationUrl}"); } using (var writer = new BlittableJsonTextWriter(context, stream)) { var current = parameters.Version; while (true) { if (parameters.CancellationToken.IsCancellationRequested) { throw new OperationCanceledException($"Stopped TCP negotiation for {parameters.Operation} because of cancellation request"); } SendTcpVersionInfo(context, writer, parameters, current); var version = parameters.ReadResponseAndGetVersionCallback(context, writer, stream, parameters.DestinationUrl); if (Log.IsInfoEnabled) { Log.Info($"Read response from {parameters.SourceNodeTag ?? parameters.DestinationUrl} for '{parameters.Operation}', received version is '{version}'"); } if (version == current) { break; } //In this case we usually throw internally but for completeness we better handle it if (version == DropStatus) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(TcpConnectionHeaderMessage.OperationTypes.Drop, TcpConnectionHeaderMessage.DropBaseLine)); } var status = TcpConnectionHeaderMessage.OperationVersionSupported(parameters.Operation, version, out current); if (status == TcpConnectionHeaderMessage.SupportedStatus.OutOfRange) { SendTcpVersionInfo(context, writer, parameters, OutOfRangeStatus); throw new ArgumentException($"The {parameters.Operation} version {parameters.Version} is out of range, our lowest version is {current}"); } if (Log.IsInfoEnabled) { Log.Info($"The version {version} is {status}, will try to agree on '{current}' for {parameters.Operation} with {parameters.DestinationNodeTag ?? parameters.DestinationUrl}."); } } if (Log.IsInfoEnabled) { Log.Info($"{parameters.DestinationNodeTag ?? parameters.DestinationUrl} agreed on version '{current}' for {parameters.Operation}."); } return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(parameters.Operation, current)); } }
public static TcpConnectionHeaderMessage.SupportedFeatures NegotiateProtocolVersion(JsonOperationContext documentsContext, Stream stream, TcpNegotiateParamaters parameters) { using (var writer = new BlittableJsonTextWriter(documentsContext, stream)) { var currentVersion = parameters.Version; while (true) { documentsContext.Write(writer, new DynamicJsonValue { [nameof(TcpConnectionHeaderMessage.DatabaseName)] = parameters.Database, // _parent.Database.Name, [nameof(TcpConnectionHeaderMessage.Operation)] = parameters.Operation.ToString(), [nameof(TcpConnectionHeaderMessage.SourceNodeTag)] = parameters.NodeTag, [nameof(TcpConnectionHeaderMessage.OperationVersion)] = currentVersion }); writer.Flush(); var version = parameters.ReadResponseAndGetVersion(documentsContext, writer, stream, parameters.Url); //In this case we usally throw internaly but for completeness we better handle it if (version == -2) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(TcpConnectionHeaderMessage.OperationTypes.Drop, TcpConnectionHeaderMessage.DropBaseLine40000)); } var(supported, prevSupported) = TcpConnectionHeaderMessage.OperationVersionSupported(parameters.Operation, version); if (supported) { //We are done if (currentVersion == version) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(parameters.Operation, version)); } //Here we support the requested version but need to inform the otherside we agree currentVersion = version; continue; } if (prevSupported == -1) { return(TcpConnectionHeaderMessage.GetSupportedFeaturesFor(TcpConnectionHeaderMessage.OperationTypes.None, TcpConnectionHeaderMessage.NoneBaseLine40000)); } currentVersion = prevSupported; } } }