Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Process/ChipPreparation/ChipPreparationRequestHandler.cs

333 lines
14 KiB
C#
Raw Normal View History

using MainShell.Alarm;
using MainShell.Common;
using MainShell.Log;
using MainShell.Vision;
using MW.WorkFlow;
using Stylet;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace MainShell.Process
{
public class ChipPreparationRequestHandler : IHandle<ChipPreparationRequestedEventArgs>, IHandle<ChipPreparationStateChangedEventArgs>, IDisposable
{
private readonly IEventAggregator _eventAggregator;
private readonly PreparationAreaService _preparationAreaService;
private readonly AlarmOperate _alarmOperate;
private readonly WorkflowRunner _workflowRunner;
private readonly SemaphoreSlim _serialGate = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim _runnerStateGate = new SemaphoreSlim(1, 1);
private readonly CancellationTokenSource _disposeCts = new CancellationTokenSource();
private bool _disposed;
public ChipPreparationRequestHandler(IEventAggregator eventAggregator, PreparationAreaService preparationAreaService, AlarmOperate alarmOperate)
{
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
_preparationAreaService = preparationAreaService ?? throw new ArgumentNullException(nameof(preparationAreaService));
_alarmOperate = alarmOperate ?? throw new ArgumentNullException(nameof(alarmOperate));
_workflowRunner = new WorkflowRunner();
_eventAggregator.Subscribe(this);
}
public void Handle(ChipPreparationRequestedEventArgs message)
{
if (message == null || message.Request == null)
{
return;
}
ChipPreparationRequest request = CloneRequest(message.Request);
_ = ProcessRequestAsync(request);
}
public void Handle(ChipPreparationStateChangedEventArgs message)
{
if (message == null || message.Snapshot == null)
{
return;
}
ChipPreparationStateSnapshot snapshot = CloneSnapshot(message.Snapshot);
_ = SynchronizeRunnerStateAsync(snapshot);
}
public void Dispose()
{
if (_disposed)
{
return;
}
_disposed = true;
_disposeCts.Cancel();
_eventAggregator.Unsubscribe(this);
_workflowRunner.Dispose();
_disposeCts.Dispose();
_serialGate.Dispose();
_runnerStateGate.Dispose();
}
private async Task ProcessRequestAsync(ChipPreparationRequest request)
{
bool gateEntered = false;
try
{
await _serialGate.WaitAsync(_disposeCts.Token);
gateEntered = true;
string.Format("Chip preparation request started. {0}.", BuildRequestSummary(request)).LogProcessInfo();
ChipPreparationWaitResult executeResult = await ExecuteOnDemandActivityAsync(request);
string rejectReason;
if (executeResult.Success)
{
_preparationAreaService.TryMarkReady(request.RequestId, out rejectReason);
}
else
{
string errorMessage = string.IsNullOrWhiteSpace(executeResult.ErrorMessage) ? "оƬ׼<C6AC><D7BC>ִ<EFBFBD><D6B4>ʧ<EFBFBD>ܡ<EFBFBD>" : executeResult.ErrorMessage;
_preparationAreaService.TryMarkFault(errorMessage, out rejectReason);
int? visionAlarmId = ResolveVisionAlarmId(executeResult);
if (visionAlarmId.HasValue)
{
await _alarmOperate.AlertAsync(
visionAlarmId.Value,
nameof(ChipPreparationRequestHandler),
"Vision alarm triggered",
BuildAlarmTriggerSummary(request, executeResult)).ConfigureAwait(false);
}
}
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
string.Format("Chip preparation request failed with exception. {0}. {1}", BuildRequestSummary(request), ex).LogProcessError();
string rejectReason;
_preparationAreaService.TryMarkFault("оƬ׼<C6AC><D7BC>ִ<EFBFBD><D6B4><EFBFBD>쳣: " + ex.Message, out rejectReason);
}
finally
{
if (gateEntered)
{
_serialGate.Release();
}
}
}
private async Task<ChipPreparationWaitResult> ExecuteOnDemandActivityAsync(ChipPreparationRequest request)
{
try
{
WorkflowContext context = new WorkflowContext();
context[WorkflowContextKeys.WorkflowName] = ProcessFlowName.ChipPreparationOnDemandFlow;
string activityName = request != null && request.Action == ChipPreparationAction.Unload
? ProcessFlowName.ChipUnloadExecuteActivity
: ProcessFlowName.ChipLoadExecuteActivity;
ChipPreparationExecuteActivity activity = new ChipPreparationExecuteActivity(activityName, request);
WorkflowRunCompletedEventArgs runResult = await _workflowRunner.RunActivityWithResultAsync(activity, context);
if (runResult == null)
{
string.Format("Chip preparation request returned no workflow result. {0}.", BuildRequestSummary(request)).LogProcessError();
return ChipPreparationWaitResult.CreateFailure("оƬ׼<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>ִ<EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>");
}
switch (runResult.FinalState)
{
case WorkflowState.Completed:
string.Format("Chip preparation request completed. {0}, FinalState={1}.", BuildRequestSummary(request), runResult.FinalState).LogProcessInfo();
return ChipPreparationWaitResult.CreateSuccess();
case WorkflowState.Canceled:
string.Format("Chip preparation request canceled. {0}, FinalState={1}, ErrorMessage={2}.", BuildRequestSummary(request), runResult.FinalState, NormalizeLogValue(runResult.Error)).LogProcessError();
return ChipPreparationWaitResult.CreateCanceled("оƬ׼<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>");
case WorkflowState.Faulted:
string.Format("Chip preparation request faulted. {0}, FinalState={1}, ErrorMessage={2}.", BuildRequestSummary(request), runResult.FinalState, NormalizeLogValue(runResult.Error)).LogProcessError();
return ChipPreparationWaitResult.CreateFailure(string.IsNullOrWhiteSpace(runResult.Error)
? "оƬ׼<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>ʧ<EFBFBD>ܡ<EFBFBD>"
: runResult.Error);
default:
string.Format("Chip preparation request returned unexpected state. {0}, FinalState={1}, ErrorMessage={2}.", BuildRequestSummary(request), runResult.FinalState, NormalizeLogValue(runResult.Error)).LogProcessError();
return ChipPreparationWaitResult.CreateFailure(string.Format("оƬ׼<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD>̷<EFBFBD><CCB7><EFBFBD><EFBFBD><EFBFBD>δԤ<CEB4><D4A4>״̬: {0}<7D><>", runResult.FinalState));
}
}
catch (Exception ex)
{
string.Format("Chip preparation workflow execution threw an exception. {0}. {1}", BuildRequestSummary(request), ex).LogProcessError();
return ChipPreparationWaitResult.CreateFailure(ex.Message);
}
}
private async Task SynchronizeRunnerStateAsync(ChipPreparationStateSnapshot snapshot)
{
if (snapshot == null || _disposed)
{
return;
}
await _runnerStateGate.WaitAsync(_disposeCts.Token).ConfigureAwait(false);
try
{
if (snapshot.Status == ChipPreparationStatus.Paused)
{
string.Format("Chip preparation runner paused. {0}.", BuildSnapshotSummary(snapshot)).LogProcessDebug();
_workflowRunner.Pause();
return;
}
if (snapshot.Status == ChipPreparationStatus.Preparing ||
snapshot.Status == ChipPreparationStatus.Loading ||
snapshot.Status == ChipPreparationStatus.Unloading)
{
string.Format("Chip preparation runner resumed. {0}.", BuildSnapshotSummary(snapshot)).LogProcessDebug();
_workflowRunner.Resume();
return;
}
if ((snapshot.Status == ChipPreparationStatus.Idle || snapshot.Status == ChipPreparationStatus.Faulted) &&
_workflowRunner.IsRunning)
{
string.Format("Chip preparation runner stopping. {0}.", BuildSnapshotSummary(snapshot)).LogProcessDebug();
await _workflowRunner.StopAsync().ConfigureAwait(false);
}
}
catch (OperationCanceledException)
{
}
finally
{
_runnerStateGate.Release();
}
}
private static ChipPreparationRequest CloneRequest(ChipPreparationRequest request)
{
if (request == null)
{
return null;
}
return new ChipPreparationRequest
{
RequestId = request.RequestId,
RecipeName = request.RecipeName,
Action = request.Action,
SourceStepId = request.SourceStepId
};
}
private static ChipPreparationStateSnapshot CloneSnapshot(ChipPreparationStateSnapshot snapshot)
{
if (snapshot == null)
{
return null;
}
return new ChipPreparationStateSnapshot
{
Status = snapshot.Status,
ActiveRequestId = snapshot.ActiveRequestId,
RecipeName = snapshot.RecipeName,
SourceStepId = snapshot.SourceStepId,
CurrentStage = snapshot.CurrentStage,
ErrorMessage = snapshot.ErrorMessage,
LastUpdatedTime = snapshot.LastUpdatedTime,
CurrentAction = snapshot.CurrentAction,
IsChipLoaded = snapshot.IsChipLoaded
};
}
private static int? ResolveVisionAlarmId(ChipPreparationWaitResult executeResult)
{
if (executeResult == null)
{
return null;
}
if (!string.IsNullOrWhiteSpace(executeResult.ErrorMessage) &&
executeResult.ErrorMessage.IndexOf("Vision", StringComparison.OrdinalIgnoreCase) >= 0)
{
return VisionAlarmIds.TemplateMatchFailed;
}
return null;
}
private static string BuildRequestSummary(ChipPreparationRequest request)
{
if (request == null)
{
return "RequestId=N/A, Action=None, RecipeName=N/A, SourceStepId=N/A";
}
return string.Format(
"RequestId={0}, Action={1}, RecipeName={2}, SourceStepId={3}",
NormalizeLogValue(request.RequestId),
request.Action,
NormalizeLogValue(request.RecipeName),
NormalizeLogValue(request.SourceStepId));
}
private static string BuildSnapshotSummary(ChipPreparationStateSnapshot snapshot)
{
if (snapshot == null)
{
return "Status=N/A, ActiveRequestId=N/A, CurrentAction=None, SourceStepId=N/A, IsChipLoaded=False";
}
return string.Format(
"Status={0}, ActiveRequestId={1}, CurrentAction={2}, SourceStepId={3}, IsChipLoaded={4}",
snapshot.Status,
NormalizeLogValue(snapshot.ActiveRequestId),
snapshot.CurrentAction,
NormalizeLogValue(snapshot.SourceStepId),
snapshot.IsChipLoaded);
}
private static string BuildAlarmTriggerSummary(ChipPreparationRequest request, ChipPreparationWaitResult executeResult)
{
return string.Format(
"{0}, ErrorMessage={1}",
BuildRequestSummary(request),
executeResult == null ? "N/A" : NormalizeLogValue(executeResult.ErrorMessage));
}
private static string NormalizeLogValue(string value)
{
return string.IsNullOrWhiteSpace(value) ? "N/A" : value;
}
}
public class ChipPreparationExecuteActivity : ActivityAbstractBase
{
private readonly ChipPreparationRequest _request;
public ChipPreparationExecuteActivity(string name, ChipPreparationRequest request)
: base(name)
{
_request = request;
}
protected override async Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
{
if (_request == null)
{
return ActivityResult.Failure;
}
for (int i = 0; i < 3; i++)
{
activityControl.ThrowIfCancellationRequested();
await activityControl.CheckPauseAsync();
await Task.Delay(300, activityControl.CancellationToken);
}
return ActivityResult.Success;
}
}
}