diff --git a/samples/DtmSample/Controllers/WfTestController.cs b/samples/DtmSample/Controllers/WfTestController.cs index 0f1d71a..474efa3 100644 --- a/samples/DtmSample/Controllers/WfTestController.cs +++ b/samples/DtmSample/Controllers/WfTestController.cs @@ -6,12 +6,14 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; +using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Exception = System.Exception; namespace DtmSample.Controllers { @@ -65,6 +67,52 @@ public async Task Simple(CancellationToken cancellationToken) } } + [HttpPost("wf-twice")] + public async Task SimpleTwice(CancellationToken cancellationToken) + { + try + { + string wfNameReturnNormal = $"wfNameReturnNormal-{Guid.NewGuid().ToString("N")[..8]}"; + _globalTransaction.Register(wfNameReturnNormal, async (wf, data) => await Task.FromResult(Encoding.UTF8.GetBytes("my result"))); + string wfNameReturnEmpty = $"wfNameReturnEmpty-{Guid.NewGuid().ToString("N")[..8]}"; + _globalTransaction.Register(wfNameReturnEmpty, async (wf, data) => await Task.FromResult(Encoding.UTF8.GetBytes(""))); + string wfNameReturnNull = $"wfNameReturnNull-{Guid.NewGuid().ToString("N")[..8]}"; + _globalTransaction.Register(wfNameReturnNull, (wf, data) => Task.FromResult(null)); + + string req = JsonSerializer.Serialize(new TransRequest("1", -30)); + + string gid; + byte[] result1, result2; + string resultStr1, resultStr2; + gid = wfNameReturnNormal + " " + Guid.NewGuid().ToString("N"); + result1 = await _globalTransaction.Execute(wfNameReturnNormal, gid, Encoding.UTF8.GetBytes(req), true); + result2 = await _globalTransaction.Execute(wfNameReturnNormal, gid, Encoding.UTF8.GetBytes(req), true); + resultStr1 = Encoding.UTF8.GetString(result1); + resultStr2 = Encoding.UTF8.GetString(result2); + if ("my result" != resultStr1) throw new Exception("\"my result\" != resultStr1"); + if (resultStr1 != resultStr2) throw new Exception("resultStr1 != resultStr2"); + + gid = wfNameReturnEmpty + " " + Guid.NewGuid().ToString("N"); + result1 = await _globalTransaction.Execute(wfNameReturnEmpty, gid, Encoding.UTF8.GetBytes(req), true); + result2 = await _globalTransaction.Execute(wfNameReturnEmpty, gid, Encoding.UTF8.GetBytes(req), true); + if (null != result1) throw new Exception("String.Empty != resultStr1"); + if (result1 != result2) throw new Exception("resultStr1 != resultStr2"); + + gid = wfNameReturnNull + " " + Guid.NewGuid().ToString("N"); + result1 = await _globalTransaction.Execute(wfNameReturnNull, gid, Encoding.UTF8.GetBytes(req), true); + result2 = await _globalTransaction.Execute(wfNameReturnNull, gid, Encoding.UTF8.GetBytes(req), true); + if (null != result1) throw new Exception("String.Empty != resultStr1"); + if (result1 != result2) throw new Exception("resultStr1 != resultStr2"); + + return Ok(TransResponse.BuildSucceedResponse()); + } + catch (Exception ex) + { + _logger.LogError(ex, "Workflow Error"); + return Ok(TransResponse.BuildFailureResponse()); + } + } + [HttpPost("wf-saga")] public async Task Saga(CancellationToken cancellationToken) { diff --git a/src/Dtmworkflow/Workflow.Imp.cs b/src/Dtmworkflow/Workflow.Imp.cs index 669e24f..53e6e07 100644 --- a/src/Dtmworkflow/Workflow.Imp.cs +++ b/src/Dtmworkflow/Workflow.Imp.cs @@ -39,7 +39,9 @@ internal async Task Process(WfFunc2 handler, byte[] data) var status = reply.Transaction.Status; if (status == DtmCommon.Constant.StatusSucceed) { - var sRes = Convert.FromBase64String(reply.Transaction.Result); + var sRes = reply.Transaction.Result != null + ? Convert.FromBase64String(reply.Transaction.Result) + : null; return sRes; } else if (status == DtmCommon.Constant.StatusFailed) @@ -75,11 +77,15 @@ internal async Task Process(WfFunc2 handler, byte[] data) } if (err == null || err is DtmCommon.DtmFailureException) - { + { + // The DTM server does not distinguish between byte[0] and null, + // when execute the second time (eg. executeByQs), the previous query result returned is null. await this.Submit(res, err, default); } - - return res; + + // Before the DTM server side (v1.18.0) distinguish between byte[0] and null, + // in order to be compatible with the same return values for twice call, byte[] has been uniformly changed to return null. + return (res != null && res.Length == 0) ? null : res; } private async Task SaveResult(string branchId, string op, StepResult sr)