Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Process/ChipPreparation/ChipPreparationRequestHandler.cs
Shi.Ji e31d3560bb 添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
2026-05-18 11:43:09 +08:00

333 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}