Skip to content

Adds more write overloads to Utf8Json #4209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@ public SerializerRegistrationInformation(Type type, string purpose)
public override string ToString() => _stringRepresentation;
}

//TODO this no longer needs to be IInternalSerializerWithFormatter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does DiagnosticsSerializerProxy still need to implement IInternalSerializerWithFormatter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove it instead since its internal

// 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.
/// <summary>
/// Wraps configured serializer so that we can emit diagnostics per configured serializer.
/// </summary>
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);
Expand All @@ -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))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
using Elasticsearch.Net.Extensions;
using Elasticsearch.Net.Utf8Json;

namespace Elasticsearch.Net
{
public static class ElasticsearchSerializerExtensions
{
internal static void SerializeUsingWriter<T>(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);
}

/// <summary>
/// Extension method that serializes an instance of <typeparamref name="T"/> to a byte array.
/// </summary>
Expand Down Expand Up @@ -65,5 +79,6 @@ public static string SerializeToString<T>(
return ms.Utf8String();
}
}

}
}
Original file line number Diff line number Diff line change
@@ -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; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(Stream stream)
{
return JsonSerializer.Deserialize<T>(stream, ElasticsearchNetFormatterResolver.Instance);
}

public Task<object> DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default)
{
return JsonSerializer.NonGeneric.DeserializeAsync(type, stream, ElasticsearchNetFormatterResolver.Instance);
}

public Task<T> DeserializeAsync<T>(Stream stream, CancellationToken cancellationToken = default)
{
return JsonSerializer.DeserializeAsync<T>(stream, ElasticsearchNetFormatterResolver.Instance);
}
public object Deserialize(Type type, Stream stream) =>
JsonSerializer.NonGeneric.Deserialize(type, stream, ElasticsearchNetFormatterResolver.Instance);

public T Deserialize<T>(Stream stream) =>
JsonSerializer.Deserialize<T>(stream, ElasticsearchNetFormatterResolver.Instance);

public Task<object> DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default) =>
JsonSerializer.NonGeneric.DeserializeAsync(type, stream, ElasticsearchNetFormatterResolver.Instance);

public Task<T> DeserializeAsync<T>(Stream stream, CancellationToken cancellationToken = default) =>
JsonSerializer.DeserializeAsync<T>(stream, ElasticsearchNetFormatterResolver.Instance);

public void Serialize<T>(T data, Stream writableStream, SerializationFormatting formatting = SerializationFormatting.None) =>
JsonSerializer.Serialize(writableStream, data, ElasticsearchNetFormatterResolver.Instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterReso
/// `IInternalSerializerWithFormatter`
/// </summary>
private static bool AttemptFastPath(IElasticsearchSerializer serializer) =>
serializer is IInternalSerializerWithFormatter s && s.FormatterResolver != null;
serializer is IInternalSerializer s && s.TryGetJsonFormatter(out var _);


public virtual void Serialize(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver)
Expand Down
7 changes: 7 additions & 0 deletions src/Nest/Document/Multiple/Bulk/BulkRequestFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ public void Serialize(ref JsonWriter writer, IBulkRequest value, IJsonFormatterR
if (body == null)
continue;

if (op.Operation == "update" || body is ILazyDocument)
{
var requestResponseSerializer = settings.RequestResponseSerializer;
requestResponseSerializer.SerializeUsingWriter(ref writer, body, settings, SerializationFormatting.None);
return;
}

SourceWriter.Serialize(ref writer, body, formatterResolver);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a behavioural change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because SerializationFormatting.None is not specified explicitly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavioural change looks like the SourceWriter is now always used.

Before, the requestResponseSerializer was used when the operation was an update or the body was an ILazyDocument

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh you are right, will address!

writer.WriteRaw(Newline);
}
Expand Down
10 changes: 7 additions & 3 deletions src/Tests/Tests.Benchmarking/BenchmarkProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down