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;
                }
            }
        }
Exemple #2
0
        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;
         }
     }
 }