Skip to content

Instantly share code, notes, and snippets.

@angusbreno
Created September 30, 2021 12:59
Show Gist options
  • Save angusbreno/9b3f97fe1d332c5be00c62c431031d5a to your computer and use it in GitHub Desktop.
Save angusbreno/9b3f97fe1d332c5be00c62c431031d5a to your computer and use it in GitHub Desktop.
ProcessResults
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MarQ.Results
{
public class AggregateProcessResult : ProcessResult, IDictionary<string, ProcessResult>
{
public Dictionary<string, ProcessResult> Results { get; set; } = new Dictionary<string, ProcessResult>();
public AggregateException GetAggregateException()
{
//Error
var failedResults = Results.Where(x => !x.Value.Succeed).ToList();
if (Errors.Count > 0)
{
failedResults.Insert(0, new KeyValuePair<string, ProcessResult>("Principal", this));
}
var message = failedResults.SelectMany(x => x.Value.Errors)?.Select(x => x.Title).Aggregate((x, y) => x + " - " + y);
return new AggregateException(message, failedResults.Select(x => new Exception(x.Key + " - "+ x.Value)));
}
#region IDictionary<string, ProcessResult>
public ProcessResult this[string key] { get => Results[key]; set => Results[key] = value; }
public ICollection<string> Keys => Results.Keys;
public ICollection<ProcessResult> Values => Results.Values;
public int Count => Results.Count;
public bool IsReadOnly => false;
public void Add(string key, ProcessResult value)
{
Results.Add(key, value);
}
public bool AddCheckSucceeded(string key, ProcessResult value)
{
Results.Add(key, value);
return value.Succeed;
}
public void Add(KeyValuePair<string, ProcessResult> item)
{
Results.Add(item.Key, item.Value);
}
public void Clear()
{
Results.Clear();
}
public bool Contains(KeyValuePair<string, ProcessResult> item)
{
return Results.ContainsKey(item.Key);
}
public bool ContainsKey(string key)
{
return Results.ContainsKey(key);
}
public void CopyTo(KeyValuePair<string, ProcessResult>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public IEnumerator<KeyValuePair<string, ProcessResult>> GetEnumerator()
{
return Results.GetEnumerator();
}
public bool Remove(string key)
{
return Results.Remove(key);
}
public bool Remove(KeyValuePair<string, ProcessResult> item)
{
return Results.Remove(item.Key);
}
public bool TryGetValue(string key, out ProcessResult value)
{
return Results.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace MarQ.Results
{
public class ProcessResult
{
public static ProcessResult Empty = new ProcessResult() { Succeed = true };
public void Start()
{
StartedAt = DateTimeOffset.UtcNow;
}
public void Finish()
{
FinishInternal(true);
}
public void Finish(Exception exception)
{
FinishInternal(false);
var iex = exception;
do
{
Errors.Add(
new ProcessResultError()
{
Title = iex.Message,
//Detail = GetExceptionDebugInfo(iex)
});
iex = iex.InnerException;
}
while (iex != null);
}
//private string GetExceptionDebugInfo(Exception iex)
//{
// try
// {
// var st = new StackTrace(exception, true);
// return st.ToString();
// }
// catch (Exception)
// {
// return string.Empty;
// }
//}
public string Id { get; set; }
public bool Succeed { get; set; }
public List<string> Logs { get; set; } = new List<string>();
public List<ProcessResultError> Errors { get; set; } = new List<ProcessResultError>();
public bool Started { get { return StartedAt != null; } }
public DateTimeOffset? StartedAt { get; set; }
public bool Finished { get { return FinishedAt != null; } }
public DateTimeOffset? FinishedAt { get; set; }
public TimeSpan? Duration { get { return GetDuration(); } }
private TimeSpan? GetDuration()
{
if (StartedAt == null) { return null; }
if (FinishedAt == null)
{
return DateTime.UtcNow - StartedAt;
}
else
{
return FinishedAt - StartedAt;
}
}
public string GetLogs()
{
var slog = "";
foreach (var log in Logs)
{
slog += log + "; " + Environment.NewLine;
}
return slog;
}
public void AddLog(string log)
{
Logs.Add($"{Duration?.ToString("c")}: {log}");
}
protected void FinishInternal(bool succeed)
{
FinishedAt = DateTimeOffset.UtcNow;
Succeed = succeed;
}
}
public class ProcessResultError
{
public string Title { get; set; }
public string Detail { get; set; }
}
}
public async Task<ProcessResult> RegisterImage(RegisterPointCommandBase registerCommand, byte[] imageBytes)
{
var r = new ProcessResult();
try
{
r.Start();
//OK
r.Finish();
}
catch (Exception ex)
{
r.Finish(ex);
}
return r;
}
public async Task<AggregateProcessResult> RegisterPointPropagateCache(string userPointCacheId, PerformContext performContext = null)
{
var result = new AggregateProcessResult();
result.Start();
var cache = Repository.Entities.FirstOrDefault(x => x.Id == userPointCacheId);
if (cache == null) { return null; }
try
{
//SignIn(cache.CompanyId, null, true);
var imageResult = await userPointImageService.RegisterImage(cache.RegisterCommand, cache.ImageBytes);
if (!result.AddCheckSucceeded("image", imageResult))
{
throw new Exception("Image register failed");
}
var registerPointResult = await userPointWorkshiftService.RegisterPoint(cache.RegisterCommand);
if (!result.AddCheckSucceeded("point", registerPointResult))
{
throw new Exception("Register point failed");
}
result.Finish();
}
catch (Exception ex)
{
if (ex.Message.Contains(PointsErrorCodes.WorkshiftNotFound.ToString()))
{
//if workshift not found dont retry job.
performContext.SetJobParameter("RetryCount", "999");
}
result.Finish(ex);
}
if (!result.Succeed)
{
cache.Status = Models.UserPointCacheStatus.Error;
cache.StatusMessage = JsonConvert.SerializeObject(result);
}
else
{
cache.Status = Models.UserPointCacheStatus.Completed;
}
await CommitAsync();
return result.Succeed ?
result : throw result.GetAggregateException();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment