Skip to content

Commit 5ebe0b0

Browse files
committed
initial add async versions ser/deser
1 parent 833406f commit 5ebe0b0

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

src/Abstractions/DataConverter.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,46 @@ public abstract class DataConverter
4949
/// </returns>
5050
[return: NotNullIfNotNull("data")]
5151
public virtual T? Deserialize<T>(string? data) => (T?)(this.Deserialize(data, typeof(T)) ?? default);
52+
53+
/// <summary>
54+
/// Asynchronously serializes <paramref name="value"/> into a text string.
55+
/// Default implementation delegates to <see cref="Serialize(object?)"/>.
56+
/// </summary>
57+
/// <param name="value">The value to be serialized.</param>
58+
/// <param name="cancellationToken">Cancellation token.</param>
59+
/// <returns>A task whose result is the serialized string or <c>null</c>.</returns>
60+
public virtual ValueTask<string?> SerializeAsync(object? value, CancellationToken cancellationToken = default)
61+
{
62+
return new ValueTask<string?>(this.Serialize(value));
63+
}
64+
65+
/// <summary>
66+
/// Asynchronously deserializes <paramref name="data"/> into an object of type <paramref name="targetType"/>.
67+
/// Default implementation delegates to <see cref="Deserialize(string?, Type)"/>.
68+
/// </summary>
69+
/// <param name="data">The text data to be deserialized.</param>
70+
/// <param name="targetType">The type to deserialize to.</param>
71+
/// <param name="cancellationToken">Cancellation token.</param>
72+
/// <returns>A task whose result is the deserialized value or <c>null</c>.</returns>
73+
public virtual ValueTask<object?> DeserializeAsync(
74+
string? data,
75+
Type targetType,
76+
CancellationToken cancellationToken = default)
77+
{
78+
return new ValueTask<object?>(this.Deserialize(data, targetType));
79+
}
80+
81+
/// <summary>
82+
/// Asynchronously deserializes <paramref name="data"/> into an object of type <typeparamref name="T"/>.
83+
/// </summary>
84+
/// <typeparam name="T">The type to deserialize to.</typeparam>
85+
/// <param name="data">The text data to be deserialized.</param>
86+
/// <param name="cancellationToken">Cancellation token.</param>
87+
/// <returns>A task whose result is the deserialized value or <c>null</c>.</returns>
88+
public virtual ValueTask<T?> DeserializeAsync<T>(
89+
string? data,
90+
CancellationToken cancellationToken = default)
91+
{
92+
return new ValueTask<T?>(this.Deserialize<T>(data));
93+
}
5294
}

src/Extensions/AzureBlobPayloads/Converters/LargePayloadDataConverter.cs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
using System.Diagnostics.CodeAnalysis;
45
using System.Text;
56

67
namespace Microsoft.DurableTask.Converters;
@@ -20,25 +21,39 @@ namespace Microsoft.DurableTask.Converters;
2021
public sealed class LargePayloadDataConverter(
2122
DataConverter innerConverter,
2223
IPayloadStore payloadStore,
23-
LargePayloadStorageOptions largePayloadStorageOptions
24-
) : DataConverter
24+
LargePayloadStorageOptions largePayloadStorageOptions) : DataConverter
2525
{
26-
2726
readonly DataConverter innerConverter = innerConverter ?? throw new ArgumentNullException(nameof(innerConverter));
2827
readonly IPayloadStore payLoadStore = payloadStore ?? throw new ArgumentNullException(nameof(payloadStore));
2928
readonly LargePayloadStorageOptions largePayloadStorageOptions = largePayloadStorageOptions ?? throw new ArgumentNullException(nameof(largePayloadStorageOptions));
29+
3030
// Use UTF-8 without a BOM (encoderShouldEmitUTF8Identifier=false). JSON in UTF-8 should not include a
3131
// byte order mark per RFC 8259, and omitting it avoids hidden extra bytes that could skew the
3232
// externalization threshold calculation and prevents interop issues with strict JSON parsers.
3333
// A few legacy tools rely on a BOM for encoding detection, but modern JSON tooling assumes BOM-less UTF-8.
3434
readonly Encoding utf8 = new UTF8Encoding(false);
3535

36+
/// <inheritdoc/>
37+
[return: NotNullIfNotNull("value")]
38+
public override string? Serialize(object? value)
39+
{
40+
throw new NotImplementedException();
41+
}
42+
43+
/// <inheritdoc/>
44+
[return: NotNullIfNotNull("data")]
45+
public override object? Deserialize(string? data, Type targetType)
46+
{
47+
throw new NotImplementedException();
48+
}
49+
3650
/// <summary>
3751
/// Serializes the value to a JSON string and uploads it to the external payload store if it exceeds the configured threshold.
3852
/// </summary>
3953
/// <param name="value">The value to serialize.</param>
54+
/// <param name="cancellationToken">Cancellation token.</param>
4055
/// <returns>The serialized value or the token if externalized.</returns>
41-
public override string? Serialize(object? value)
56+
public override async ValueTask<string?> SerializeAsync(object? value, CancellationToken cancellationToken = default)
4257
{
4358
string? json = this.innerConverter.Serialize(value);
4459

@@ -55,17 +70,20 @@ LargePayloadStorageOptions largePayloadStorageOptions
5570

5671
// Upload synchronously in this context by blocking on async. SDK call sites already run on threadpool.
5772
byte[] bytes = this.utf8.GetBytes(json);
58-
string token = this.payLoadStore.UploadAsync(bytes, CancellationToken.None).GetAwaiter().GetResult();
59-
return token;
73+
return await this.payLoadStore.UploadAsync(bytes, cancellationToken);
6074
}
6175

6276
/// <summary>
6377
/// Deserializes the JSON string or resolves the token to the original value.
6478
/// </summary>
6579
/// <param name="data">The JSON string or token.</param>
6680
/// <param name="targetType">The type to deserialize to.</param>
81+
/// <param name="cancellationToken">Cancellation token.</param>
6782
/// <returns>The deserialized value.</returns>
68-
public override object? Deserialize(string? data, Type targetType)
83+
public override async ValueTask<object?> DeserializeAsync(
84+
string? data,
85+
Type targetType,
86+
CancellationToken cancellationToken = default)
6987
{
7088
if (data is null)
7189
{
@@ -75,7 +93,7 @@ LargePayloadStorageOptions largePayloadStorageOptions
7593
string toDeserialize = data;
7694
if (this.payLoadStore.IsKnownPayloadToken(data))
7795
{
78-
toDeserialize = this.payLoadStore.DownloadAsync(data, CancellationToken.None).GetAwaiter().GetResult();
96+
toDeserialize = await this.payLoadStore.DownloadAsync(data, CancellationToken.None);
7997
}
8098

8199
return this.innerConverter.Deserialize(StripArrayCharacters(toDeserialize), targetType);
@@ -92,5 +110,3 @@ LargePayloadStorageOptions largePayloadStorageOptions
92110
return input;
93111
}
94112
}
95-
96-

0 commit comments

Comments
 (0)