Skip to content

Commit

Permalink
Add optimistic concurrency updates to comment
Browse files Browse the repository at this point in the history
Retrieve Etag and use If-Match when updating comment.

WIP: need to wait for https://github.com/orgs/community/discussions/50084 to be fixed, then uncomment `return etag != null`
  • Loading branch information
kzu committed Jul 12, 2024
1 parent cc9375c commit b1e89d0
Showing 2 changed files with 37 additions and 5 deletions.
5 changes: 1 addition & 4 deletions src/dotnet-trx/Process.cs
Original file line number Diff line number Diff line change
@@ -40,9 +40,6 @@ static bool TryExecuteCore(ProcessStartInfo info, string? input, out string? out
try
{
info.StandardOutputEncoding = Encoding.UTF8;
//if (input != null)
// info.StandardInputEncoding = Encoding.UTF8;

var proc = System.Diagnostics.Process.Start(info);
if (proc == null)
{
@@ -69,7 +66,7 @@ static bool TryExecuteCore(ProcessStartInfo info, string? input, out string? out
}

var error = proc.StandardError.ReadToEnd();
gotError |= error.Length > 0;
gotError |= error.Trim().Length > 0;
output = output.Trim();
if (string.IsNullOrEmpty(output))
output = null;
37 changes: 36 additions & 1 deletion src/dotnet-trx/TrxCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
@@ -335,7 +336,41 @@ static void AppendBadges(Summary summary, StringBuilder builder, string elapsed,
{
// API requires a json payload
File.WriteAllText(input, JsonSerializer.Serialize(new { body }));
TryExecute("gh", $"api repos/{repo}/issues/comments/{commentId} -X PATCH --input {input}", out _);
static bool TryGetETag(string repo, long comment, [NotNullWhen(true)] out string? etag)
{
etag = null;
if (TryExecute("gh", $"api -i repos/{repo}/issues/comments/{comment}", out var headers) &&
headers?.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(x => x.StartsWith("Etag:", StringComparison.OrdinalIgnoreCase)) is { } etagHeader)
etag = etagHeader.Split(":")[1].Trim();

// TODO: this DOES NOT WORK FOR NOW
// See https://github.com/orgs/community/discussions/50084
//return etag != null;
return false;
}

if (TryGetETag(repo, commentId, out var etag))
{
// If we're patching, we need to do optimistic concurrency check to avoid losing updates
while (!TryExecute("gh",
[
"api",
"-H", $"if-match: {etag}",
"-X", "PATCH",
$"repos/{repo}/issues/comments/{commentId}",
"--input", input
], out _))
{
if (!TryGetETag(repo, commentId, out var newEtag) || newEtag == etag)
break;

etag = newEtag;
}
}
else
{
TryExecute("gh", $"api repos/{repo}/issues/comments/{commentId} -X PATCH --input {input}", out _);
}
}
else
{

0 comments on commit b1e89d0

Please sign in to comment.