|
6 | 6 |
|
7 | 7 | using System.Diagnostics; |
8 | 8 | using System.Globalization; |
9 | | -using System.Text; |
| 9 | +using System.Text.Json; |
| 10 | +using System.Text.Json.Serialization; |
10 | 11 |
|
11 | 12 | namespace Aspire.Shared; |
12 | 13 |
|
@@ -68,9 +69,8 @@ public static BundleVersionLease Acquire(string versionDirectory, string holderK |
68 | 69 |
|
69 | 70 | try |
70 | 71 | { |
71 | | - var metadata = CreateMetadataJson(fullVersionDirectory, holderKind, commandName); |
72 | | - var bytes = Encoding.UTF8.GetBytes(metadata); |
73 | | - stream.Write(bytes); |
| 72 | + var metadata = CreateMetadata(fullVersionDirectory, holderKind, commandName); |
| 73 | + JsonSerializer.Serialize(stream, metadata, BundleVersionLeaseJsonSerializerContext.Default.BundleVersionLeaseMetadata); |
74 | 74 | stream.Flush(flushToDisk: true); |
75 | 75 |
|
76 | 76 | return new BundleVersionLease(fullVersionDirectory, leasePath, stream); |
@@ -208,49 +208,31 @@ private static long GetCurrentProcessStartTimeTicks() |
208 | 208 | } |
209 | 209 | } |
210 | 210 |
|
211 | | - private static string CreateMetadataJson(string versionDirectory, string holderKind, string? commandName) |
| 211 | + private static BundleVersionLeaseMetadata CreateMetadata(string versionDirectory, string holderKind, string? commandName) |
212 | 212 | { |
213 | 213 | var versionId = Path.GetFileName(versionDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); |
214 | 214 | var startTicks = GetCurrentProcessStartTimeTicks(); |
215 | | - var acquired = DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture); |
216 | 215 |
|
217 | | - return $$""" |
218 | | - { |
219 | | - "versionId": "{{EscapeJson(versionId)}}", |
220 | | - "versionDirectory": "{{EscapeJson(versionDirectory)}}", |
221 | | - "processId": {{Environment.ProcessId}}, |
222 | | - "processStartTimeUtcTicks": {{startTicks}}, |
223 | | - "holderKind": "{{EscapeJson(holderKind)}}", |
224 | | - "commandName": "{{EscapeJson(commandName)}}", |
225 | | - "acquiredUtc": "{{acquired}}" |
226 | | - } |
227 | | - """; |
228 | | - } |
229 | | - |
230 | | - private static string EscapeJson(string? value) |
231 | | - { |
232 | | - if (string.IsNullOrEmpty(value)) |
233 | | - { |
234 | | - return string.Empty; |
235 | | - } |
236 | | - |
237 | | - var builder = new StringBuilder(value.Length); |
238 | | - foreach (var ch in value) |
239 | | - { |
240 | | - _ = ch switch |
241 | | - { |
242 | | - '"' => builder.Append("\\\""), |
243 | | - '\\' => builder.Append("\\\\"), |
244 | | - '\b' => builder.Append("\\b"), |
245 | | - '\f' => builder.Append("\\f"), |
246 | | - '\n' => builder.Append("\\n"), |
247 | | - '\r' => builder.Append("\\r"), |
248 | | - '\t' => builder.Append("\\t"), |
249 | | - < ' ' => builder.Append(CultureInfo.InvariantCulture, $"\\u{(int)ch:x4}"), |
250 | | - _ => builder.Append(ch) |
251 | | - }; |
252 | | - } |
253 | | - |
254 | | - return builder.ToString(); |
| 216 | + return new BundleVersionLeaseMetadata( |
| 217 | + VersionId: versionId, |
| 218 | + VersionDirectory: versionDirectory, |
| 219 | + ProcessId: Environment.ProcessId, |
| 220 | + ProcessStartTimeUtcTicks: startTicks, |
| 221 | + HolderKind: holderKind, |
| 222 | + CommandName: commandName, |
| 223 | + AcquiredUtc: DateTimeOffset.UtcNow); |
255 | 224 | } |
256 | 225 | } |
| 226 | + |
| 227 | +internal sealed record BundleVersionLeaseMetadata( |
| 228 | + string? VersionId, |
| 229 | + string VersionDirectory, |
| 230 | + int ProcessId, |
| 231 | + long ProcessStartTimeUtcTicks, |
| 232 | + string HolderKind, |
| 233 | + string? CommandName, |
| 234 | + DateTimeOffset AcquiredUtc); |
| 235 | + |
| 236 | +[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, WriteIndented = true)] |
| 237 | +[JsonSerializable(typeof(BundleVersionLeaseMetadata))] |
| 238 | +internal sealed partial class BundleVersionLeaseJsonSerializerContext : JsonSerializerContext; |
0 commit comments