diff --git a/src/Elasticsearch.Net/Serialization/DiagnosticsSerializerProxy.cs b/src/Elasticsearch.Net/Serialization/DiagnosticsSerializerProxy.cs index 668ecd6860a..22a3af50d19 100644 --- a/src/Elasticsearch.Net/Serialization/DiagnosticsSerializerProxy.cs +++ b/src/Elasticsearch.Net/Serialization/DiagnosticsSerializerProxy.cs @@ -32,12 +32,16 @@ public SerializerRegistrationInformation(Type type, string purpose) public override string ToString() => _stringRepresentation; } + //TODO this no longer needs to be IInternalSerializerWithFormatter + // Previous we checked that the serializer we are wrapping implements the interface and if so set the formatter + // However its totally fine for formatter to be null. `IJsonFormatter` solves this better. /// /// Wraps configured serializer so that we can emit diagnostics per configured serializer. /// - internal class DiagnosticsSerializerProxy : IElasticsearchSerializer, IInternalSerializerWithFormatter + internal class DiagnosticsSerializerProxy : IElasticsearchSerializer, IInternalSerializerWithFormatter, IInternalSerializer { private readonly IElasticsearchSerializer _serializer; + private readonly bool _wrapsUtf8JsonSerializer; private readonly SerializerRegistrationInformation _state; private readonly IJsonFormatterResolver _formatterResolver; private static DiagnosticSource DiagnosticSource { get; } = new DiagnosticListener(DiagnosticSources.Serializer.SourceName); @@ -47,11 +51,25 @@ public DiagnosticsSerializerProxy(IElasticsearchSerializer serializer, string pu _serializer = serializer; _state = new SerializerRegistrationInformation(serializer.GetType(), purpose); if (serializer is IInternalSerializerWithFormatter withFormatter) + { _formatterResolver = withFormatter.FormatterResolver; + _wrapsUtf8JsonSerializer = true; + } + else + { + _wrapsUtf8JsonSerializer = false; + _formatterResolver = null; + } } public IJsonFormatterResolver FormatterResolver => _formatterResolver; + public bool TryGetJsonFormatter(out IJsonFormatterResolver formatterResolver) + { + formatterResolver = _formatterResolver; + return _wrapsUtf8JsonSerializer; + } + public object Deserialize(Type type, Stream stream) { using (DiagnosticSource.Diagnose(DiagnosticSources.Serializer.Deserialize, _state)) diff --git a/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs b/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs index a32d4e8f4ab..c686dc58438 100644 --- a/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs +++ b/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs @@ -1,9 +1,23 @@ using Elasticsearch.Net.Extensions; +using Elasticsearch.Net.Utf8Json; namespace Elasticsearch.Net { public static class ElasticsearchSerializerExtensions { + internal static void SerializeUsingWriter(this IElasticsearchSerializer serializer, ref JsonWriter writer, T body, IConnectionConfigurationValues settings, SerializationFormatting formatting) + { + if (serializer is IInternalSerializer s && s.TryGetJsonFormatter(out var formatterResolver)) + { + JsonSerializer.Serialize(ref writer, body, formatterResolver); + return; + } + + var memoryStreamFactory = settings.MemoryStreamFactory; + var bodyBytes = serializer.SerializeToBytes(body, memoryStreamFactory, formatting); + writer.WriteRaw(bodyBytes); + } + /// /// Extension method that serializes an instance of to a byte array. /// @@ -65,5 +79,6 @@ public static string SerializeToString( return ms.Utf8String(); } } + } } diff --git a/src/Elasticsearch.Net/Serialization/IInternalSerializerWithFormatter.cs b/src/Elasticsearch.Net/Serialization/IInternalSerializerWithFormatter.cs index 48285f1e8df..6f050b69b6a 100644 --- a/src/Elasticsearch.Net/Serialization/IInternalSerializerWithFormatter.cs +++ b/src/Elasticsearch.Net/Serialization/IInternalSerializerWithFormatter.cs @@ -1,9 +1,14 @@ using Elasticsearch.Net.Utf8Json; -namespace Elasticsearch.Net +namespace Elasticsearch.Net { + internal interface IInternalSerializer + { + bool TryGetJsonFormatter(out IJsonFormatterResolver formatterResolver); + } + internal interface IInternalSerializerWithFormatter { IJsonFormatterResolver FormatterResolver { get; } } -} \ No newline at end of file +} diff --git a/src/Elasticsearch.Net/Serialization/LowLevelRequestResponseSerializer.cs b/src/Elasticsearch.Net/Serialization/LowLevelRequestResponseSerializer.cs index 57fe93064de..2a6445d8791 100644 --- a/src/Elasticsearch.Net/Serialization/LowLevelRequestResponseSerializer.cs +++ b/src/Elasticsearch.Net/Serialization/LowLevelRequestResponseSerializer.cs @@ -7,29 +7,23 @@ namespace Elasticsearch.Net { - public class LowLevelRequestResponseSerializer : IElasticsearchSerializer + public class LowLevelRequestResponseSerializer : IElasticsearchSerializer, IInternalSerializerWithFormatter { + IJsonFormatterResolver IInternalSerializerWithFormatter.FormatterResolver => null; + public static readonly LowLevelRequestResponseSerializer Instance = new LowLevelRequestResponseSerializer(); - public object Deserialize(Type type, Stream stream) - { - return JsonSerializer.NonGeneric.Deserialize(type, stream, ElasticsearchNetFormatterResolver.Instance); - } - - public T Deserialize(Stream stream) - { - return JsonSerializer.Deserialize(stream, ElasticsearchNetFormatterResolver.Instance); - } - - public Task DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default) - { - return JsonSerializer.NonGeneric.DeserializeAsync(type, stream, ElasticsearchNetFormatterResolver.Instance); - } - - public Task DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) - { - return JsonSerializer.DeserializeAsync(stream, ElasticsearchNetFormatterResolver.Instance); - } + public object Deserialize(Type type, Stream stream) => + JsonSerializer.NonGeneric.Deserialize(type, stream, ElasticsearchNetFormatterResolver.Instance); + + public T Deserialize(Stream stream) => + JsonSerializer.Deserialize(stream, ElasticsearchNetFormatterResolver.Instance); + + public Task DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default) => + JsonSerializer.NonGeneric.DeserializeAsync(type, stream, ElasticsearchNetFormatterResolver.Instance); + + public Task DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) => + JsonSerializer.DeserializeAsync(stream, ElasticsearchNetFormatterResolver.Instance); public void Serialize(T data, Stream writableStream, SerializationFormatting formatting = SerializationFormatting.None) => JsonSerializer.Serialize(writableStream, data, ElasticsearchNetFormatterResolver.Instance); diff --git a/src/Elasticsearch.Net/Utf8Json/IJsonFormatterResolver.cs b/src/Elasticsearch.Net/Utf8Json/IJsonFormatterResolver.cs index e9ae1be023d..429c8576236 100644 --- a/src/Elasticsearch.Net/Utf8Json/IJsonFormatterResolver.cs +++ b/src/Elasticsearch.Net/Utf8Json/IJsonFormatterResolver.cs @@ -23,6 +23,7 @@ #endregion using System; +using System.Collections.Concurrent; using System.Reflection; namespace Elasticsearch.Net.Utf8Json @@ -60,11 +61,10 @@ public static IJsonFormatter GetFormatterWithVerify(this IJsonFormatterRes return formatter; } + private static readonly MethodInfo _getFormatterMethod = typeof(IJsonFormatterResolver).GetRuntimeMethod("GetFormatter", Type.EmptyTypes); public static object GetFormatterDynamic(this IJsonFormatterResolver resolver, Type type) { - var methodInfo = typeof(IJsonFormatterResolver).GetRuntimeMethod("GetFormatter", Type.EmptyTypes); - - var formatter = methodInfo.MakeGenericMethod(type).Invoke(resolver, null); + var formatter = _getFormatterMethod.MakeGenericMethod(type).Invoke(resolver, null); return formatter; } } diff --git a/src/Elasticsearch.Net/Utf8Json/Internal/UnsafeMemory.Low.cs b/src/Elasticsearch.Net/Utf8Json/Internal/UnsafeMemory.Low.cs index 5aa3104e9a3..e0e378cb75e 100644 --- a/src/Elasticsearch.Net/Utf8Json/Internal/UnsafeMemory.Low.cs +++ b/src/Elasticsearch.Net/Utf8Json/Internal/UnsafeMemory.Low.cs @@ -35,9 +35,10 @@ internal static class UnsafeMemory { public static readonly bool Is32Bit = (IntPtr.Size == 4); - public static void WriteRaw(ref JsonWriter writer, byte[] src) + public static void WriteRaw(ref JsonWriter writer, byte[] src) => WriteRaw(ref writer, src, src.Length); + public static void WriteRaw(ref JsonWriter writer, byte[] src, int length) { - switch (src.Length) + switch (length) { case 0: break; case 1: if (Is32Bit) { UnsafeMemory32.WriteRaw1(ref writer, src); } else { UnsafeMemory64.WriteRaw1(ref writer, src); } break; @@ -77,19 +78,20 @@ public static void WriteRaw(ref JsonWriter writer, byte[] src) } } - public static unsafe void MemoryCopy(ref JsonWriter writer, byte[] src) + public static void MemoryCopy(ref JsonWriter writer, byte[] src) => MemoryCopy(ref writer, src, src.Length); + public static unsafe void MemoryCopy(ref JsonWriter writer, byte[] src, int length) { - BinaryUtil.EnsureCapacity(ref writer.buffer, writer.offset, src.Length); + BinaryUtil.EnsureCapacity(ref writer.buffer, writer.offset, length); #if !NET45 fixed (void* dstP = &writer.buffer[writer.offset]) fixed (void* srcP = &src[0]) { - Buffer.MemoryCopy(srcP, dstP, writer.buffer.Length - writer.offset, src.Length); + Buffer.MemoryCopy(srcP, dstP, writer.buffer.Length - writer.offset, length); } #else - Buffer.BlockCopy(src, 0, writer.buffer, writer.offset, src.Length); + Buffer.BlockCopy(src, 0, writer.buffer, writer.offset, length); #endif - writer.offset += src.Length; + writer.offset += length; } } diff --git a/src/Elasticsearch.Net/Utf8Json/JsonWriter.cs b/src/Elasticsearch.Net/Utf8Json/JsonWriter.cs index 06b2a08ac23..2d1b8fed2c0 100644 --- a/src/Elasticsearch.Net/Utf8Json/JsonWriter.cs +++ b/src/Elasticsearch.Net/Utf8Json/JsonWriter.cs @@ -23,6 +23,7 @@ #endregion using System; +using System.IO; using System.Runtime.CompilerServices; using System.Text; using Elasticsearch.Net.Extensions; @@ -147,6 +148,27 @@ public void WriteRaw(byte[] rawValue) offset += rawValue.Length; #endif } + public void WriteRaw(byte[] rawValue, int length) + { + UnsafeMemory.WriteRaw(ref this, rawValue, length); + } + public void WriteRaw(MemoryStream ms) + { + if (ms.TryGetBuffer(out var b) && !(b.Array is null) && b.Offset == 0) + WriteRaw(b.Array, b.Count); + else + { + var bytes = ms.ToArray(); + this.WriteRaw(bytes); + } + } + + public void WriteSerialized(T value, IElasticsearchSerializer serializer, IConnectionConfigurationValues settings, SerializationFormatting formatting = SerializationFormatting.None) + { + using var ms = settings.MemoryStreamFactory.Create(); + serializer.Serialize(value, ms, formatting); + WriteRaw(ms); + } #if NETSTANDARD [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -483,5 +505,6 @@ private static void ToUnicode(char c, ref int offset, byte[] buffer) buffer[offset++] = (byte)CharUtils.HexDigit((c >> 4) & '\x000f'); buffer[offset++] = (byte)CharUtils.HexDigit(c & '\x000f'); } + } } diff --git a/src/Elasticsearch.Net/Utf8Json/Resolvers/CompositeResolver.cs b/src/Elasticsearch.Net/Utf8Json/Resolvers/CompositeResolver.cs index d4390e6b161..f88be4ab4c4 100644 --- a/src/Elasticsearch.Net/Utf8Json/Resolvers/CompositeResolver.cs +++ b/src/Elasticsearch.Net/Utf8Json/Resolvers/CompositeResolver.cs @@ -157,7 +157,7 @@ internal abstract class DynamicCompositeResolver : IJsonFormatterResolver { private static readonly string ModuleName = $"{ResolverConfig.Namespace}.DynamicCompositeResolver"; - static readonly DynamicAssembly assembly; + static readonly DynamicAssembly assembly; static DynamicCompositeResolver() { diff --git a/src/Nest/CommonAbstractions/Extensions/TypeExtensions.cs b/src/Nest/CommonAbstractions/Extensions/TypeExtensions.cs index f731a526b22..5223e8aab3a 100644 --- a/src/Nest/CommonAbstractions/Extensions/TypeExtensions.cs +++ b/src/Nest/CommonAbstractions/Extensions/TypeExtensions.cs @@ -5,6 +5,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; +using Elasticsearch.Net.CrossPlatform; namespace Nest { @@ -150,5 +151,9 @@ private static bool IsHidingMember(PropertyInfo propertyInfo) } internal delegate T ObjectActivator(params object[] args); + + private static readonly Assembly NestAssembly = typeof(TypeExtensions).Assembly(); + + public static bool IsNestType(this Type type) => type.Assembly() == NestAssembly; } } diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/DefaultHighLevelSerializer.cs b/src/Nest/CommonAbstractions/SerializationBehavior/DefaultHighLevelSerializer.cs index 1b7a625b158..c7239ec465f 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/DefaultHighLevelSerializer.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/DefaultHighLevelSerializer.cs @@ -14,25 +14,17 @@ internal class DefaultHighLevelSerializer : IElasticsearchSerializer, IInternalS public IJsonFormatterResolver FormatterResolver { get; } - public T Deserialize(Stream stream) - { - return JsonSerializer.Deserialize(stream, FormatterResolver); - } - - public object Deserialize(Type type, Stream stream) - { - return JsonSerializer.NonGeneric.Deserialize(type, stream, FormatterResolver); - } - - public Task DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) - { - return JsonSerializer.DeserializeAsync(stream, FormatterResolver); - } - - public Task DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default) - { - return JsonSerializer.NonGeneric.DeserializeAsync(type, stream, FormatterResolver); - } + public T Deserialize(Stream stream) => + JsonSerializer.Deserialize(stream, FormatterResolver); + + public object Deserialize(Type type, Stream stream) => + JsonSerializer.NonGeneric.Deserialize(type, stream, FormatterResolver); + + public Task DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) => + JsonSerializer.DeserializeAsync(stream, FormatterResolver); + + public Task DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default) => + JsonSerializer.NonGeneric.DeserializeAsync(type, stream, FormatterResolver); public virtual void Serialize(T data, Stream writableStream, SerializationFormatting formatting = SerializationFormatting.None) => JsonSerializer.Serialize(writableStream, data, FormatterResolver); diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/ProxyRequestFormatterBase.cs b/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/ProxyRequestFormatterBase.cs index 9013eff29d0..0961df6844a 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/ProxyRequestFormatterBase.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/ProxyRequestFormatterBase.cs @@ -37,8 +37,7 @@ public void Serialize(ref JsonWriter writer, TRequestInterface value, IJsonForma using (var ms = settings.MemoryStreamFactory.Create()) { untypedDocumentRequest.WriteJson(serializer, ms, SerializationFormatting.None); - var v = ms.ToArray(); - writer.WriteRaw(v); + writer.WriteRaw(ms); } } } diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/SourceFormatter.cs b/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/SourceFormatter.cs index 00124c73741..48695f84baa 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/SourceFormatter.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/SourceFormatter.cs @@ -17,7 +17,7 @@ public T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterReso var settings = formatterResolver.GetConnectionSettings(); // avoid deserialization through stream when not using custom source serializer - if (ReferenceEquals(settings.SourceSerializer, settings.RequestResponseSerializer)) + if (AttemptFastPath(settings.SourceSerializer)) return formatterResolver.GetFormatter().Deserialize(ref reader, formatterResolver); var arraySegment = reader.ReadNextBlockSegment(); @@ -25,12 +25,24 @@ public T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterReso return settings.SourceSerializer.Deserialize(ms); } + /// + /// Avoid serialization to bytes when not using a custom source serializer. + /// This used to check for reference of the source serializer and the request response serializer + /// However each now gets wrapped in a new `DiagnosticsSerializerProxy` so this check no longer works + /// therefor we now check if the SourceSerializer is internal with a formatter. + /// DiagnosticsSerializerProxy implements this interface, it simply proxies to whatever it wraps so + /// we need to assert the resolver is not actually null here since it can wrap something that is not + /// `IInternalSerializerWithFormatter` + /// + private static bool AttemptFastPath(IElasticsearchSerializer serializer) => + serializer is IInternalSerializer s && s.TryGetJsonFormatter(out var _); + + public virtual void Serialize(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver) { var settings = formatterResolver.GetConnectionSettings(); - // avoid serialization to bytes when not using custom source serializer - if (ReferenceEquals(settings.SourceSerializer, settings.RequestResponseSerializer)) + if (AttemptFastPath(settings.SourceSerializer)) { formatterResolver.GetFormatter().Serialize(ref writer, value, formatterResolver); return; @@ -38,15 +50,8 @@ public virtual void Serialize(ref JsonWriter writer, T value, IJsonFormatterReso var sourceSerializer = settings.SourceSerializer; var f = ForceFormatting ?? SerializationFormatting.None; - byte[] bytes; - using (var ms = settings.MemoryStreamFactory.Create()) - { - sourceSerializer.Serialize(value, ms, f); - // TODO: read each byte instead of creating and allocating an array - bytes = ms.ToArray(); - } - writer.WriteRaw(bytes); + writer.WriteSerialized(value, sourceSerializer, settings, f); } } } diff --git a/src/Nest/CommonAbstractions/SerializationBehavior/SourceValueWriteConverter.cs b/src/Nest/CommonAbstractions/SerializationBehavior/SourceValueWriteConverter.cs index 964305e0280..2c0e5a3ca71 100644 --- a/src/Nest/CommonAbstractions/SerializationBehavior/SourceValueWriteConverter.cs +++ b/src/Nest/CommonAbstractions/SerializationBehavior/SourceValueWriteConverter.cs @@ -1,4 +1,3 @@ -using Elasticsearch.Net.CrossPlatform; using Elasticsearch.Net.Utf8Json; namespace Nest @@ -13,8 +12,7 @@ public override void Serialize(ref JsonWriter writer, T value, IJsonFormatterRes return; } - var nestType = value.GetType().Assembly() == typeof(SourceWriteFormatter<>).Assembly(); - if (nestType) + if (value.GetType().IsNestType()) formatterResolver.GetFormatter().Serialize(ref writer, value, formatterResolver); else base.Serialize(ref writer, value, formatterResolver); diff --git a/src/Nest/Document/Multiple/Bulk/BulkRequestFormatter.cs b/src/Nest/Document/Multiple/Bulk/BulkRequestFormatter.cs index e4969b40557..86b5213b604 100644 --- a/src/Nest/Document/Multiple/Bulk/BulkRequestFormatter.cs +++ b/src/Nest/Document/Multiple/Bulk/BulkRequestFormatter.cs @@ -8,6 +8,8 @@ internal class BulkRequestFormatter : IJsonFormatter { private const byte Newline = (byte)'\n'; + private static SourceWriteFormatter SourceWriter { get; } = new SourceWriteFormatter(); + public IBulkRequest Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) => throw new NotSupportedException(); @@ -17,16 +19,13 @@ public void Serialize(ref JsonWriter writer, IBulkRequest value, IJsonFormatterR return; var settings = formatterResolver.GetConnectionSettings(); - var memoryStreamFactory = settings.MemoryStreamFactory; - var requestResponseSerializer = settings.RequestResponseSerializer; - var sourceSerializer = settings.SourceSerializer; var inferrer = settings.Inferrer; var formatter = formatterResolver.GetFormatter(); for (var index = 0; index < value.Operations.Count; index++) { var op = value.Operations[index]; - op.Index = op.Index ?? value.Index ?? op.ClrType; + op.Index ??= value.Index ?? op.ClrType; if (op.Index.Equals(value.Index)) op.Index = null; op.Id = op.GetIdForOperation(inferrer); op.Routing = op.GetRoutingForOperation(inferrer); @@ -42,12 +41,14 @@ public void Serialize(ref JsonWriter writer, IBulkRequest value, IJsonFormatterR if (body == null) continue; - var bodySerializer = op.Operation == "update" || body is ILazyDocument - ? requestResponseSerializer - : sourceSerializer; + if (op.Operation == "update" || body is ILazyDocument) + { + var requestResponseSerializer = settings.RequestResponseSerializer; + requestResponseSerializer.SerializeUsingWriter(ref writer, body, settings, SerializationFormatting.None); + return; + } - var bodyBytes = bodySerializer.SerializeToBytes(body, memoryStreamFactory, SerializationFormatting.None); - writer.WriteRaw(bodyBytes); + SourceWriter.Serialize(ref writer, body, formatterResolver); writer.WriteRaw(Newline); } } diff --git a/src/Nest/Search/MultiSearch/MultiSearchFormatter.cs b/src/Nest/Search/MultiSearch/MultiSearchFormatter.cs index de46ef816d0..06652dfebce 100644 --- a/src/Nest/Search/MultiSearch/MultiSearchFormatter.cs +++ b/src/Nest/Search/MultiSearch/MultiSearchFormatter.cs @@ -44,11 +44,9 @@ public void Serialize(ref JsonWriter writer, IMultiSearchRequest value, IJsonFor ignore_unavailable = GetString("ignore_unavailable") }; - var headerBytes = serializer.SerializeToBytes(header, memoryStreamFactory, SerializationFormatting.None); - writer.WriteRaw(headerBytes); + writer.WriteSerialized(header, serializer, settings, SerializationFormatting.None); writer.WriteRaw(Newline); - var bodyBytes = serializer.SerializeToBytes(operation, memoryStreamFactory, SerializationFormatting.None); - writer.WriteRaw(bodyBytes); + writer.WriteSerialized(operation, serializer, settings, SerializationFormatting.None); writer.WriteRaw(Newline); } } diff --git a/src/Nest/Search/MultiSearchTemplate/MultiSearchTemplateJsonConverter.cs b/src/Nest/Search/MultiSearchTemplate/MultiSearchTemplateJsonConverter.cs index 6a44955a798..c7a31e2a396 100644 --- a/src/Nest/Search/MultiSearchTemplate/MultiSearchTemplateJsonConverter.cs +++ b/src/Nest/Search/MultiSearchTemplate/MultiSearchTemplateJsonConverter.cs @@ -44,11 +44,9 @@ string GetString(string key) ignore_unavailable = GetString("ignore_unavailable") }; - var headerBytes = serializer.SerializeToBytes(header, memoryStreamFactory, SerializationFormatting.None); - writer.WriteRaw(headerBytes); + writer.WriteSerialized(header, serializer, settings, SerializationFormatting.None); writer.WriteRaw(Newline); - var bodyBytes = serializer.SerializeToBytes(operation, memoryStreamFactory, SerializationFormatting.None); - writer.WriteRaw(bodyBytes); + writer.WriteSerialized(operation, serializer, settings, SerializationFormatting.None); writer.WriteRaw(Newline); } } diff --git a/src/Nest/XPack/MachineLearning/PostJobData/PostJobDataRequest.cs b/src/Nest/XPack/MachineLearning/PostJobData/PostJobDataRequest.cs index ace7e6fdda8..66621c4cded 100644 --- a/src/Nest/XPack/MachineLearning/PostJobData/PostJobDataRequest.cs +++ b/src/Nest/XPack/MachineLearning/PostJobData/PostJobDataRequest.cs @@ -63,14 +63,9 @@ public void Serialize(ref JsonWriter writer, IPostJobDataRequest value, IJsonFor var settings = formatterResolver.GetConnectionSettings(); var sourceSerializer = settings.SourceSerializer; - var memoryStreamFactory = settings.MemoryStreamFactory; foreach (var data in value.Data) - { - var bodyJson = sourceSerializer.SerializeToBytes(data, memoryStreamFactory, SerializationFormatting.None); - writer.WriteRaw(bodyJson); - writer.WriteRaw(Newline); - } + writer.WriteSerialized(data, sourceSerializer, settings, SerializationFormatting.None); } } } diff --git a/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs b/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs index 2a262555974..84ddbb0f00d 100644 --- a/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs +++ b/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs @@ -30,15 +30,19 @@ static Program() if (!Directory.Exists(Path.Combine(dirInfo.FullName, ".git"))) Environment.Exit(2); Console.WriteLine(dirInfo.FullName); - using (var repos = new Repository(dirInfo.FullName)) + try { + using var repos = new Repository(dirInfo.FullName); Commit = repos.Head.Tip.Sha; CommitMessage = repos.Head.Tip.Message?.Trim(' ', '\t', '\r', '\n'); Branch = repos.Head.FriendlyName; var remoteName = repos.Head.RemoteName; Repository = - repos.Network.Remotes.FirstOrDefault(r => r.Name == remoteName)?.Url - ?? repos.Network.Remotes.FirstOrDefault()?.Url; + repos.Network.Remotes.FirstOrDefault(r => r.Name == remoteName)?.Url; + } + catch (Exception) + { + // ignored, libgit not very linux friendly } }