添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Recipe.Models;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipLoadRequestActivity : ActivityAbstractBase
|
||||
{
|
||||
public ChipLoadRequestActivity(string name, TimeSpan? timeout = null) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
activityControl.ThrowIfCancellationRequested();
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
ChipPreparationRequest request = new ChipPreparationRequest
|
||||
{
|
||||
RecipeName = ResolveRecipeName(context),
|
||||
Action = ChipPreparationAction.Load,
|
||||
SourceStepId = ResolveSourceStepId(context)
|
||||
};
|
||||
|
||||
string rejectReason;
|
||||
if (preparationAreaService.TryRequestPrepare(request, out rejectReason))
|
||||
{
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
return Task.FromResult(Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE><C6AC>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܾ<F3B1BBBE><DCBE><EFBFBD>" : rejectReason
|
||||
}));
|
||||
}
|
||||
|
||||
private static string ResolveRecipeName(WorkflowContext context)
|
||||
{
|
||||
if (context.TryGetData<RecipeManager>(WorkflowContextKeys.RecipeManager, out var recipeManager) &&
|
||||
recipeManager != null &&
|
||||
recipeManager.CurrentWaferRecipe != null)
|
||||
{
|
||||
return recipeManager.CurrentWaferRecipe.RecipeName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string ResolveSourceStepId(WorkflowContext context)
|
||||
{
|
||||
if (context.TryGetData<string>(WorkflowContextKeys.CurrentStepId, out var stepId))
|
||||
{
|
||||
return stepId;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Recipe.Models;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipPreparationAutoLoadStartActivity : ActivityAbstractBase
|
||||
{
|
||||
public ChipPreparationAutoLoadStartActivity(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
activityControl.ThrowIfCancellationRequested();
|
||||
|
||||
bool pendingChipLoad;
|
||||
if (context.TryGetData<bool>(WorkflowContextKeys.PendingChipLoad, out pendingChipLoad) && !pendingChipLoad)
|
||||
{
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
CurrentChipStateService currentChipStateService;
|
||||
if (!context.TryGetData<CurrentChipStateService>(WorkflowContextKeys.CurrentChipStateService, out currentChipStateService) || currentChipStateService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>ǰоƬ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
if (currentChipStateService.CurrentState != CurrentChipLifecycleState.Empty)
|
||||
{
|
||||
context.SetData(WorkflowContextKeys.PendingChipLoad, false);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, currentChipStateService.CurrentState);
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
ChipPreparationRequest request = new ChipPreparationRequest
|
||||
{
|
||||
RecipeName = ResolveRecipeName(context),
|
||||
Action = ChipPreparationAction.Load,
|
||||
SourceStepId = ResolveSourceStepId(context)
|
||||
};
|
||||
|
||||
string rejectReason;
|
||||
if (preparationAreaService.TryRequestPrepare(request, out rejectReason) || CanIgnoreReject(preparationAreaService.CurrentStatus))
|
||||
{
|
||||
currentChipStateService.SetState(CurrentChipLifecycleState.Loading);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Loading);
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
return Task.FromResult(Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : rejectReason
|
||||
}));
|
||||
}
|
||||
|
||||
private static bool CanIgnoreReject(ChipPreparationStatus status)
|
||||
{
|
||||
return status == ChipPreparationStatus.Preparing ||
|
||||
status == ChipPreparationStatus.Loading ||
|
||||
status == ChipPreparationStatus.Loaded;
|
||||
}
|
||||
|
||||
private static string ResolveRecipeName(WorkflowContext context)
|
||||
{
|
||||
RecipeManager recipeManager;
|
||||
if (context.TryGetData<RecipeManager>(WorkflowContextKeys.RecipeManager, out recipeManager) &&
|
||||
recipeManager != null &&
|
||||
recipeManager.CurrentWaferRecipe != null)
|
||||
{
|
||||
return recipeManager.CurrentWaferRecipe.RecipeName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string ResolveSourceStepId(WorkflowContext context)
|
||||
{
|
||||
string stepId;
|
||||
if (context.TryGetData<string>(WorkflowContextKeys.CurrentStepId, out stepId))
|
||||
{
|
||||
return stepId;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using MainShell.Common;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipPreparationConsumeActivity : ActivityAbstractBase
|
||||
{
|
||||
public ChipPreparationConsumeActivity(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
activityControl.ThrowIfCancellationRequested();
|
||||
|
||||
CurrentChipLifecycleState currentChipState;
|
||||
if (!context.TryGetData<CurrentChipLifecycleState>(WorkflowContextKeys.CurrentChipState, out currentChipState) ||
|
||||
currentChipState != CurrentChipLifecycleState.LoadedPendingTransfer)
|
||||
{
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
AutoProductionRuntimeStateService autoProductionRuntimeStateService;
|
||||
if (!context.TryGetData<AutoProductionRuntimeStateService>(WorkflowContextKeys.AutoProductionRuntimeStateService, out autoProductionRuntimeStateService) || autoProductionRuntimeStateService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
string rejectReason;
|
||||
if (preparationAreaService.TryConsumeReady(out rejectReason))
|
||||
{
|
||||
CurrentChipStateService currentChipStateService;
|
||||
if (context.TryGetData<CurrentChipStateService>(WorkflowContextKeys.CurrentChipStateService, out currentChipStateService) && currentChipStateService != null)
|
||||
{
|
||||
currentChipStateService.SetState(CurrentChipLifecycleState.InUse);
|
||||
}
|
||||
|
||||
autoProductionRuntimeStateService.SetCurrentChipRemainingCount(1);
|
||||
|
||||
context.SetData(WorkflowContextKeys.PendingChipLoad, false);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.InUse);
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipRemainingCount, autoProductionRuntimeStateService.CurrentChipRemainingCount);
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
return Task.FromResult(Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE><C6AC>̨<CCA8><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : rejectReason
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,925 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.ProcessResult;
|
||||
using MW.WorkFlow;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public enum ChipPreparationAction
|
||||
{
|
||||
None = 0,
|
||||
Load = 1,
|
||||
Unload = 2,
|
||||
Completed = 3,
|
||||
Prepare = 4
|
||||
}
|
||||
|
||||
public enum ChipPreparationStatus
|
||||
{
|
||||
Idle = 0,
|
||||
Preparing = 1,
|
||||
Prepared = 2,
|
||||
Paused = 3,
|
||||
Faulted = 4,
|
||||
Loading = 5,
|
||||
Loaded = 6,
|
||||
Unloading = 7
|
||||
}
|
||||
|
||||
public class ChipPreparationRequest
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public string RecipeName { get; set; }
|
||||
|
||||
public ChipPreparationAction Action { get; set; } = ChipPreparationAction.Prepare;
|
||||
|
||||
public string SourceStepId { get; set; }
|
||||
}
|
||||
|
||||
public class ChipPreparationWaitResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
|
||||
public bool IsTimeout { get; set; }
|
||||
|
||||
public bool IsCanceled { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
public static ChipPreparationWaitResult CreateSuccess()
|
||||
{
|
||||
return new ChipPreparationWaitResult
|
||||
{
|
||||
Success = true
|
||||
};
|
||||
}
|
||||
|
||||
public static ChipPreparationWaitResult CreateTimeout(string errorMessage)
|
||||
{
|
||||
return new ChipPreparationWaitResult
|
||||
{
|
||||
IsTimeout = true,
|
||||
ErrorMessage = errorMessage
|
||||
};
|
||||
}
|
||||
|
||||
public static ChipPreparationWaitResult CreateCanceled(string errorMessage)
|
||||
{
|
||||
return new ChipPreparationWaitResult
|
||||
{
|
||||
IsCanceled = true,
|
||||
ErrorMessage = errorMessage
|
||||
};
|
||||
}
|
||||
|
||||
public static ChipPreparationWaitResult CreateFailure(string errorMessage)
|
||||
{
|
||||
return new ChipPreparationWaitResult
|
||||
{
|
||||
ErrorMessage = errorMessage
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class ChipPreparationStateSnapshot
|
||||
{
|
||||
public ChipPreparationStatus Status { get; set; }
|
||||
|
||||
public string ActiveRequestId { get; set; }
|
||||
|
||||
public string RecipeName { get; set; }
|
||||
|
||||
public string SourceStepId { get; set; }
|
||||
|
||||
public string CurrentStage { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
public DateTime LastUpdatedTime { get; set; }
|
||||
|
||||
public ChipPreparationAction CurrentAction { get; set; }
|
||||
|
||||
public bool IsChipLoaded { get; set; }
|
||||
}
|
||||
|
||||
public class ChipPreparationState : PropertyChangedBase
|
||||
{
|
||||
private ChipPreparationStatus _status;
|
||||
private string _activeRequestId;
|
||||
private string _recipeName;
|
||||
private string _sourceStepId;
|
||||
private string _currentStage;
|
||||
private string _errorMessage;
|
||||
private DateTime _lastUpdatedTime;
|
||||
private ChipPreparationAction _currentAction;
|
||||
private bool _isChipLoaded;
|
||||
|
||||
public ChipPreparationStatus Status
|
||||
{
|
||||
get { return _status; }
|
||||
set { SetAndNotify(ref _status, value); }
|
||||
}
|
||||
|
||||
public string ActiveRequestId
|
||||
{
|
||||
get { return _activeRequestId; }
|
||||
set { SetAndNotify(ref _activeRequestId, value); }
|
||||
}
|
||||
|
||||
public string RecipeName
|
||||
{
|
||||
get { return _recipeName; }
|
||||
set { SetAndNotify(ref _recipeName, value); }
|
||||
}
|
||||
|
||||
public string SourceStepId
|
||||
{
|
||||
get { return _sourceStepId; }
|
||||
set { SetAndNotify(ref _sourceStepId, value); }
|
||||
}
|
||||
|
||||
public string CurrentStage
|
||||
{
|
||||
get { return _currentStage; }
|
||||
set { SetAndNotify(ref _currentStage, value); }
|
||||
}
|
||||
|
||||
public string ErrorMessage
|
||||
{
|
||||
get { return _errorMessage; }
|
||||
set { SetAndNotify(ref _errorMessage, value); }
|
||||
}
|
||||
|
||||
public DateTime LastUpdatedTime
|
||||
{
|
||||
get { return _lastUpdatedTime; }
|
||||
set { SetAndNotify(ref _lastUpdatedTime, value); }
|
||||
}
|
||||
|
||||
public ChipPreparationAction CurrentAction
|
||||
{
|
||||
get { return _currentAction; }
|
||||
set { SetAndNotify(ref _currentAction, value); }
|
||||
}
|
||||
|
||||
public bool IsChipLoaded
|
||||
{
|
||||
get { return _isChipLoaded; }
|
||||
set { SetAndNotify(ref _isChipLoaded, value); }
|
||||
}
|
||||
|
||||
public bool IsBusy
|
||||
{
|
||||
get
|
||||
{
|
||||
return Status == ChipPreparationStatus.Preparing ||
|
||||
Status == ChipPreparationStatus.Loading ||
|
||||
Status == ChipPreparationStatus.Unloading;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReady
|
||||
{
|
||||
get
|
||||
{
|
||||
return Status == ChipPreparationStatus.Prepared ||
|
||||
Status == ChipPreparationStatus.Loaded ||
|
||||
(Status == ChipPreparationStatus.Idle && CurrentAction == ChipPreparationAction.Unload);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFaulted
|
||||
{
|
||||
get { return Status == ChipPreparationStatus.Faulted; }
|
||||
}
|
||||
|
||||
public void ApplySnapshot(ChipPreparationStateSnapshot snapshot)
|
||||
{
|
||||
if (snapshot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
NotifyOfPropertyChange(nameof(IsBusy));
|
||||
NotifyOfPropertyChange(nameof(IsReady));
|
||||
NotifyOfPropertyChange(nameof(IsFaulted));
|
||||
}
|
||||
}
|
||||
|
||||
public class ChipPreparationRequestedEventArgs : EventArgs
|
||||
{
|
||||
public ChipPreparationRequestedEventArgs(ChipPreparationRequest request)
|
||||
{
|
||||
Request = request;
|
||||
}
|
||||
|
||||
public ChipPreparationRequest Request { get; private set; }
|
||||
}
|
||||
|
||||
public class ChipPreparationStateChangedEventArgs : EventArgs
|
||||
{
|
||||
public ChipPreparationStateChangedEventArgs(ChipPreparationStateSnapshot snapshot)
|
||||
{
|
||||
Snapshot = snapshot;
|
||||
}
|
||||
|
||||
public ChipPreparationStateSnapshot Snapshot { get; private set; }
|
||||
}
|
||||
|
||||
public interface IChipPreparationService
|
||||
{
|
||||
ChipPreparationState Current { get; }
|
||||
|
||||
bool TryRequestPrepare(ChipPreparationRequest request, out string rejectReason);
|
||||
|
||||
Task<ChipPreparationWaitResult> WaitUntilReadyAsync(TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
Task<ChipPreparationWaitResult> WaitUntilLoadedAsync(TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
Task<ChipPreparationWaitResult> EnsurePreparedAsync(ChipPreparationRequest request, TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
bool TryMarkReady(string requestId, out string rejectReason);
|
||||
|
||||
bool TryMarkFault(string errorMessage, out string rejectReason);
|
||||
|
||||
bool TryConsumeReady(out string rejectReason);
|
||||
|
||||
Task CancelAsync(CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
void Pause();
|
||||
|
||||
void Resume();
|
||||
|
||||
bool TryResetFault(out string failureReason);
|
||||
}
|
||||
|
||||
public class ChipPreparationService : IChipPreparationService
|
||||
{
|
||||
private readonly object _syncRoot = new object();
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly ProcessResultManager _processResultManager;
|
||||
private ChipPreparationRequest _activeRequest;
|
||||
private ChipPreparationRequest _pendingLoadRequest;
|
||||
private ChipPreparationStateSnapshot _snapshot;
|
||||
|
||||
public ChipPreparationService(IEventAggregator eventAggregator, ProcessResultManager processResultManager)
|
||||
{
|
||||
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
||||
_processResultManager = processResultManager ?? throw new ArgumentNullException(nameof(processResultManager));
|
||||
_processResultManager.ReloadAll();
|
||||
_snapshot = RestoreSnapshot(_processResultManager.PreparationAreaState);
|
||||
Current = new ChipPreparationState();
|
||||
Current.ApplySnapshot(_snapshot);
|
||||
}
|
||||
|
||||
public ChipPreparationState Current { get; private set; }
|
||||
|
||||
public bool TryRequestPrepare(ChipPreparationRequest request, out string rejectReason)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
if (!TryValidateActionRequest(request, out rejectReason))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.RequestId))
|
||||
{
|
||||
request.RequestId = Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
ChipPreparationRequest requestToPublish = null;
|
||||
ChipPreparationStateSnapshot snapshotToPublish = null;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Faulted)
|
||||
{
|
||||
rejectReason = string.IsNullOrWhiteSpace(_snapshot.ErrorMessage) ? "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD>״̬<D7B4><CCAC>" : _snapshot.ErrorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Paused)
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ״̬<D7B4><CCAC>";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.Action == ChipPreparationAction.Prepare)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Preparing ||
|
||||
_snapshot.Status == ChipPreparationStatus.Prepared ||
|
||||
_snapshot.Status == ChipPreparationStatus.Loading ||
|
||||
_snapshot.Status == ChipPreparationStatus.Loaded)
|
||||
{
|
||||
rejectReason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Unloading)
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
|
||||
_activeRequest = CloneRequest(request);
|
||||
_pendingLoadRequest = null;
|
||||
_snapshot = CreateRunningSnapshot(_activeRequest, ChipPreparationStatus.Preparing, _snapshot.IsChipLoaded);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
requestToPublish = CloneRequest(_activeRequest);
|
||||
}
|
||||
else if (request.Action == ChipPreparationAction.Load)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Loaded)
|
||||
{
|
||||
rejectReason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Loading)
|
||||
{
|
||||
rejectReason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Preparing)
|
||||
{
|
||||
_pendingLoadRequest = CloneRequest(request);
|
||||
rejectReason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Unloading)
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
|
||||
_activeRequest = CloneRequest(request);
|
||||
_snapshot = CreateRunningSnapshot(_activeRequest, ChipPreparationStatus.Loading, _snapshot.IsChipLoaded);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
requestToPublish = CloneRequest(_activeRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Unloading)
|
||||
{
|
||||
rejectReason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_snapshot.IsChipLoaded && _snapshot.Status != ChipPreparationStatus.Loaded && _snapshot.Status != ChipPreparationStatus.Prepared)
|
||||
{
|
||||
rejectReason = "<22><>ǰû<C7B0>п<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>оƬ<D0BE><C6AC>";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Preparing || _snapshot.Status == ChipPreparationStatus.Loading)
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
|
||||
_activeRequest = CloneRequest(request);
|
||||
_pendingLoadRequest = null;
|
||||
_snapshot = CreateRunningSnapshot(_activeRequest, ChipPreparationStatus.Unloading, true);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
requestToPublish = CloneRequest(_activeRequest);
|
||||
}
|
||||
|
||||
rejectReason = string.Empty;
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
if (requestToPublish != null)
|
||||
{
|
||||
_eventAggregator.Publish(new ChipPreparationRequestedEventArgs(requestToPublish));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<ChipPreparationWaitResult> WaitUntilReadyAsync(TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await WaitForStateAsync(false, timeout, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<ChipPreparationWaitResult> WaitUntilLoadedAsync(TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await WaitForStateAsync(true, timeout, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<ChipPreparationWaitResult> EnsurePreparedAsync(ChipPreparationRequest request, TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
string rejectReason;
|
||||
if (!TryRequestPrepare(request, out rejectReason))
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateFailure(rejectReason);
|
||||
}
|
||||
|
||||
return await WaitUntilReadyAsync(timeout, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public bool TryMarkReady(string requestId, out string rejectReason)
|
||||
{
|
||||
ChipPreparationStateSnapshot snapshotToPublish = null;
|
||||
ChipPreparationRequest requestToPublish = null;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_activeRequest == null)
|
||||
{
|
||||
rejectReason = "<22><>ǰû<C7B0><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>е<EFBFBD>оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(requestId) &&
|
||||
!string.Equals(_activeRequest.RequestId, requestId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6>ƥ<EFBFBD>䡣";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_activeRequest.Action == ChipPreparationAction.Prepare)
|
||||
{
|
||||
if (_pendingLoadRequest != null)
|
||||
{
|
||||
_activeRequest = CloneRequest(_pendingLoadRequest);
|
||||
_pendingLoadRequest = null;
|
||||
_snapshot = CreateRunningSnapshot(_activeRequest, ChipPreparationStatus.Loading, true);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
requestToPublish = CloneRequest(_activeRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
_snapshot = CreateStableSnapshot(ChipPreparationStatus.Prepared, _activeRequest, true, "Prepared");
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
_activeRequest = null;
|
||||
}
|
||||
}
|
||||
else if (_activeRequest.Action == ChipPreparationAction.Load)
|
||||
{
|
||||
_snapshot = CreateStableSnapshot(ChipPreparationStatus.Loaded, _activeRequest, true, "LoadedPendingTransfer");
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
_activeRequest = null;
|
||||
}
|
||||
else if (_activeRequest.Action == ChipPreparationAction.Unload)
|
||||
{
|
||||
_snapshot = CreateIdleSnapshot(false);
|
||||
_snapshot.CurrentAction = ChipPreparationAction.Unload;
|
||||
_snapshot.CurrentStage = "UnloadCompleted";
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
_activeRequest = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>";
|
||||
return false;
|
||||
}
|
||||
|
||||
rejectReason = string.Empty;
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
if (requestToPublish != null)
|
||||
{
|
||||
_eventAggregator.Publish(new ChipPreparationRequestedEventArgs(requestToPublish));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryMarkFault(string errorMessage, out string rejectReason)
|
||||
{
|
||||
ChipPreparationStateSnapshot snapshotToPublish;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Idle)
|
||||
{
|
||||
rejectReason = "<22><>ǰû<C7B0><C3BB>ִ<EFBFBD><D6B4><EFBFBD>е<EFBFBD>оƬ<D0BE><C6AC><EFBFBD>̡<EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
|
||||
_snapshot = CreateFaultedSnapshot(_activeRequest, errorMessage, _snapshot.IsChipLoaded);
|
||||
_activeRequest = null;
|
||||
_pendingLoadRequest = null;
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
rejectReason = string.Empty;
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryConsumeReady(out string rejectReason)
|
||||
{
|
||||
ChipPreparationStateSnapshot snapshotToPublish;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Loaded || _snapshot.Status == ChipPreparationStatus.Prepared)
|
||||
{
|
||||
ResetToIdle(false);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
rejectReason = string.Empty;
|
||||
}
|
||||
else if (_snapshot.Status == ChipPreparationStatus.Idle && _snapshot.CurrentAction == ChipPreparationAction.Unload)
|
||||
{
|
||||
_snapshot = CreateIdleSnapshot(false);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
rejectReason = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
rejectReason = "<22><>ǰû<C7B0>п<EFBFBD><D0BF><EFBFBD><EFBFBD>ѵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Task CancelAsync(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
ChipPreparationStateSnapshot snapshotToPublish = null;
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (!IsTransientStatus(_snapshot.Status))
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
bool keepLoadedChip = _snapshot.IsChipLoaded && _snapshot.Status != ChipPreparationStatus.Unloading;
|
||||
_activeRequest = null;
|
||||
_pendingLoadRequest = null;
|
||||
_snapshot = CreateIdleSnapshot(keepLoadedChip);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
ChipPreparationStateSnapshot snapshotToPublish = null;
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (!IsTransientStatus(_snapshot.Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_snapshot = CloneSnapshot(_snapshot);
|
||||
_snapshot.Status = ChipPreparationStatus.Paused;
|
||||
_snapshot.CurrentStage = "Paused";
|
||||
_snapshot.LastUpdatedTime = DateTime.Now;
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
ChipPreparationStateSnapshot snapshotToPublish = null;
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_snapshot.Status != ChipPreparationStatus.Paused || _activeRequest == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChipPreparationStatus resumedStatus = ResolveRunningStatus(_activeRequest.Action);
|
||||
_snapshot = CloneSnapshot(_snapshot);
|
||||
_snapshot.Status = resumedStatus;
|
||||
_snapshot.CurrentStage = ResolveStageForStatus(resumedStatus);
|
||||
_snapshot.LastUpdatedTime = DateTime.Now;
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
}
|
||||
|
||||
public bool TryResetFault(out string failureReason)
|
||||
{
|
||||
ChipPreparationStateSnapshot snapshotToPublish;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_snapshot.Status != ChipPreparationStatus.Faulted)
|
||||
{
|
||||
failureReason = "<22><>ǰоƬ<C6AC><D7BC><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD>״̬<D7B4><CCAC>";
|
||||
return false;
|
||||
}
|
||||
|
||||
ResetToIdle(_snapshot.IsChipLoaded);
|
||||
snapshotToPublish = CloneSnapshot(_snapshot);
|
||||
failureReason = string.Empty;
|
||||
}
|
||||
|
||||
PublishState(snapshotToPublish);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<ChipPreparationWaitResult> WaitForStateAsync(bool requireLoaded, TimeSpan timeout, CancellationToken cancellationToken)
|
||||
{
|
||||
if (timeout <= TimeSpan.Zero)
|
||||
{
|
||||
timeout = TimeSpan.FromMilliseconds(100);
|
||||
}
|
||||
|
||||
DateTime deadline = DateTime.Now.Add(timeout);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
ChipPreparationWaitResult immediateResult = EvaluateWaitResult(requireLoaded);
|
||||
if (immediateResult != null)
|
||||
{
|
||||
return immediateResult;
|
||||
}
|
||||
|
||||
if (DateTime.Now >= deadline)
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateTimeout(requireLoaded
|
||||
? "<22>ȴ<EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɳ<EFBFBD>ʱ<EFBFBD><CAB1>"
|
||||
: "<22>ȴ<EFBFBD>оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD>ɳ<EFBFBD>ʱ<EFBFBD><CAB1>");
|
||||
}
|
||||
|
||||
await Task.Delay(50, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateCanceled(requireLoaded
|
||||
? "<22>ȴ<EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>"
|
||||
: "<22>ȴ<EFBFBD>оƬ<C6AC><D7BC><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>");
|
||||
}
|
||||
}
|
||||
|
||||
private ChipPreparationWaitResult EvaluateWaitResult(bool requireLoaded)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Faulted)
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateFailure(string.IsNullOrWhiteSpace(_snapshot.ErrorMessage)
|
||||
? "оƬ<C6AC><D7BC><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>ʧ<EFBFBD>ܡ<EFBFBD>"
|
||||
: _snapshot.ErrorMessage);
|
||||
}
|
||||
|
||||
if (requireLoaded)
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Loaded)
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateSuccess();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_snapshot.Status == ChipPreparationStatus.Prepared ||
|
||||
_snapshot.Status == ChipPreparationStatus.Loaded ||
|
||||
(_snapshot.Status == ChipPreparationStatus.Idle && _snapshot.CurrentAction == ChipPreparationAction.Unload))
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
if (_snapshot.Status == ChipPreparationStatus.Idle && _activeRequest == null)
|
||||
{
|
||||
return ChipPreparationWaitResult.CreateFailure("<22><>δ<EFBFBD><CEB4>ʼоƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD>̡<EFBFBD>") ;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetToIdle(bool keepLoadedChip)
|
||||
{
|
||||
_activeRequest = null;
|
||||
_pendingLoadRequest = null;
|
||||
_snapshot = CreateIdleSnapshot(keepLoadedChip);
|
||||
}
|
||||
|
||||
private void PublishState(ChipPreparationStateSnapshot snapshot)
|
||||
{
|
||||
if (snapshot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Current.ApplySnapshot(snapshot);
|
||||
_processResultManager.SavePreparationAreaState(snapshot);
|
||||
_eventAggregator.Publish(new ChipPreparationStateChangedEventArgs(CloneSnapshot(snapshot)));
|
||||
}
|
||||
|
||||
private static bool IsTransientStatus(ChipPreparationStatus status)
|
||||
{
|
||||
return status == ChipPreparationStatus.Preparing ||
|
||||
status == ChipPreparationStatus.Loading ||
|
||||
status == ChipPreparationStatus.Unloading ||
|
||||
status == ChipPreparationStatus.Paused;
|
||||
}
|
||||
|
||||
private static bool TryValidateActionRequest(ChipPreparationRequest request, out string rejectReason)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
rejectReason = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ա<EFBFBD>";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.Action != ChipPreparationAction.Prepare &&
|
||||
request.Action != ChipPreparationAction.Load &&
|
||||
request.Action != ChipPreparationAction.Unload)
|
||||
{
|
||||
rejectReason = "оƬ<C6AC><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>";
|
||||
return false;
|
||||
}
|
||||
|
||||
rejectReason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static ChipPreparationStatus ResolveRunningStatus(ChipPreparationAction action)
|
||||
{
|
||||
if (action == ChipPreparationAction.Prepare)
|
||||
{
|
||||
return ChipPreparationStatus.Preparing;
|
||||
}
|
||||
|
||||
if (action == ChipPreparationAction.Load)
|
||||
{
|
||||
return ChipPreparationStatus.Loading;
|
||||
}
|
||||
|
||||
return ChipPreparationStatus.Unloading;
|
||||
}
|
||||
|
||||
private static string ResolveStageForStatus(ChipPreparationStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ChipPreparationStatus.Preparing:
|
||||
return "Preparing";
|
||||
case ChipPreparationStatus.Prepared:
|
||||
return "Prepared";
|
||||
case ChipPreparationStatus.Loading:
|
||||
return "Loading";
|
||||
case ChipPreparationStatus.Loaded:
|
||||
return "LoadedPendingTransfer";
|
||||
case ChipPreparationStatus.Unloading:
|
||||
return "Unloading";
|
||||
case ChipPreparationStatus.Paused:
|
||||
return "Paused";
|
||||
case ChipPreparationStatus.Faulted:
|
||||
return "Faulted";
|
||||
default:
|
||||
return "Idle";
|
||||
}
|
||||
}
|
||||
|
||||
private static ChipPreparationStateSnapshot CreateIdleSnapshot(bool isChipLoaded)
|
||||
{
|
||||
return new ChipPreparationStateSnapshot
|
||||
{
|
||||
Status = ChipPreparationStatus.Idle,
|
||||
CurrentStage = isChipLoaded ? "LoadedPendingTransfer" : "Idle",
|
||||
LastUpdatedTime = DateTime.Now,
|
||||
CurrentAction = ChipPreparationAction.None,
|
||||
IsChipLoaded = isChipLoaded
|
||||
};
|
||||
}
|
||||
|
||||
private static ChipPreparationStateSnapshot CreateRunningSnapshot(ChipPreparationRequest request, ChipPreparationStatus status, bool isChipLoaded)
|
||||
{
|
||||
return new ChipPreparationStateSnapshot
|
||||
{
|
||||
Status = status,
|
||||
ActiveRequestId = request != null ? request.RequestId : null,
|
||||
RecipeName = request != null ? request.RecipeName : null,
|
||||
SourceStepId = request != null ? request.SourceStepId : null,
|
||||
CurrentStage = ResolveStageForStatus(status),
|
||||
LastUpdatedTime = DateTime.Now,
|
||||
CurrentAction = request != null ? request.Action : ChipPreparationAction.None,
|
||||
IsChipLoaded = isChipLoaded
|
||||
};
|
||||
}
|
||||
|
||||
private static ChipPreparationStateSnapshot CreateStableSnapshot(ChipPreparationStatus status, ChipPreparationRequest request, bool isChipLoaded, string stage)
|
||||
{
|
||||
return new ChipPreparationStateSnapshot
|
||||
{
|
||||
Status = status,
|
||||
ActiveRequestId = request != null ? request.RequestId : null,
|
||||
RecipeName = request != null ? request.RecipeName : null,
|
||||
SourceStepId = request != null ? request.SourceStepId : null,
|
||||
CurrentStage = stage,
|
||||
LastUpdatedTime = DateTime.Now,
|
||||
CurrentAction = request != null ? request.Action : ChipPreparationAction.None,
|
||||
IsChipLoaded = isChipLoaded
|
||||
};
|
||||
}
|
||||
|
||||
private static ChipPreparationStateSnapshot CreateFaultedSnapshot(ChipPreparationRequest request, string errorMessage, bool isChipLoaded)
|
||||
{
|
||||
return new ChipPreparationStateSnapshot
|
||||
{
|
||||
Status = ChipPreparationStatus.Faulted,
|
||||
ActiveRequestId = request != null ? request.RequestId : null,
|
||||
RecipeName = request != null ? request.RecipeName : null,
|
||||
SourceStepId = request != null ? request.SourceStepId : null,
|
||||
CurrentStage = "Faulted",
|
||||
ErrorMessage = string.IsNullOrWhiteSpace(errorMessage) ? "оƬ<C6AC><D7BC><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>ʧ<EFBFBD>ܡ<EFBFBD>" : errorMessage,
|
||||
LastUpdatedTime = DateTime.Now,
|
||||
CurrentAction = request != null ? request.Action : ChipPreparationAction.None,
|
||||
IsChipLoaded = isChipLoaded
|
||||
};
|
||||
}
|
||||
|
||||
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 ChipPreparationStateSnapshot RestoreSnapshot(PreparationAreaProcessState persistedState)
|
||||
{
|
||||
if (persistedState == null)
|
||||
{
|
||||
return CreateIdleSnapshot(false);
|
||||
}
|
||||
|
||||
return new ChipPreparationStateSnapshot
|
||||
{
|
||||
Status = persistedState.Status,
|
||||
ActiveRequestId = persistedState.ActiveRequestId,
|
||||
RecipeName = persistedState.RecipeName,
|
||||
SourceStepId = persistedState.SourceStepId,
|
||||
CurrentStage = string.IsNullOrWhiteSpace(persistedState.CurrentStage)
|
||||
? ResolveStageForStatus(persistedState.Status)
|
||||
: persistedState.CurrentStage,
|
||||
ErrorMessage = persistedState.ErrorMessage,
|
||||
LastUpdatedTime = persistedState.LastUpdatedTime == default(DateTime)
|
||||
? DateTime.Now
|
||||
: persistedState.LastUpdatedTime,
|
||||
CurrentAction = persistedState.CurrentAction,
|
||||
IsChipLoaded = persistedState.HasPreparedChip
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using MainShell.Common;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipPreparationSyncActivity : ActivityAbstractBase
|
||||
{
|
||||
private readonly TimeSpan _timeout;
|
||||
|
||||
public ChipPreparationSyncActivity(string name, TimeSpan? timeout = null)
|
||||
: base(name)
|
||||
{
|
||||
_timeout = timeout ?? TimeSpan.FromSeconds(30);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
SubstrateLifecycleState substrateState;
|
||||
if (!context.TryGetData<SubstrateLifecycleState>(WorkflowContextKeys.SubstrateProcessState, out substrateState) ||
|
||||
substrateState != SubstrateLifecycleState.HeightMeasured)
|
||||
{
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>ɲ<EFBFBD><C9B2>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD>оƬͬ<C6AC><CDAC><EFBFBD>㡣"
|
||||
});
|
||||
}
|
||||
|
||||
bool pendingChipLoad;
|
||||
if (context.TryGetData<bool>(WorkflowContextKeys.PendingChipLoad, out pendingChipLoad) && !pendingChipLoad)
|
||||
{
|
||||
return ActivityResult.Success;
|
||||
}
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
ChipPreparationWaitResult waitResult = await preparationAreaService.WaitUntilLoadedAsync(_timeout, activityControl.CancellationToken).ConfigureAwait(false);
|
||||
if (!waitResult.Success)
|
||||
{
|
||||
if (waitResult.IsCanceled)
|
||||
{
|
||||
SetWorkflowFailure(context, string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "оƬͬ<C6AC><CDAC><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>" : waitResult.ErrorMessage);
|
||||
return ActivityResult.Canceled;
|
||||
}
|
||||
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "оƬͬ<C6AC><CDAC><EFBFBD>ȴ<EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : waitResult.ErrorMessage
|
||||
});
|
||||
}
|
||||
|
||||
CurrentChipStateService currentChipStateService;
|
||||
if (!context.TryGetData<CurrentChipStateService>(WorkflowContextKeys.CurrentChipStateService, out currentChipStateService) || currentChipStateService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>ǰоƬ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
currentChipStateService.SetState(CurrentChipLifecycleState.LoadedPendingTransfer);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.LoadedPendingTransfer);
|
||||
context.SetData(WorkflowContextKeys.PendingChipLoad, false);
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
return ActivityResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using MainShell.Common;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipPreparationWaitActivity : ActivityAbstractBase
|
||||
{
|
||||
private readonly TimeSpan _timeout;
|
||||
private readonly bool _consumeOnSuccess;
|
||||
|
||||
public ChipPreparationWaitActivity(string name, TimeSpan? timeout = null, bool consumeOnSuccess = false)
|
||||
: base(name)
|
||||
{
|
||||
_timeout = timeout ?? TimeSpan.FromSeconds(30);
|
||||
_consumeOnSuccess = consumeOnSuccess;
|
||||
}
|
||||
|
||||
protected override async Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
ChipPreparationWaitResult waitResult = await preparationAreaService.WaitUntilReadyAsync(_timeout, activityControl.CancellationToken).ConfigureAwait(false);
|
||||
if (!waitResult.Success)
|
||||
{
|
||||
if (waitResult.IsCanceled)
|
||||
{
|
||||
SetWorkflowFailure(context, string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "<22>ȴ<EFBFBD>оƬ<D0BE><C6AC>̨<CCA8><D7BC><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>" : waitResult.ErrorMessage);
|
||||
return ActivityResult.Canceled;
|
||||
}
|
||||
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "<22>ȴ<EFBFBD>оƬ<D0BE><C6AC>̨<CCA8><D7BC>ʧ<EFBFBD>ܡ<EFBFBD>" : waitResult.ErrorMessage
|
||||
});
|
||||
}
|
||||
|
||||
if (!_consumeOnSuccess)
|
||||
{
|
||||
return ActivityResult.Success;
|
||||
}
|
||||
|
||||
string rejectReason;
|
||||
if (preparationAreaService.TryConsumeReady(out rejectReason))
|
||||
{
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
return ActivityResult.Success;
|
||||
}
|
||||
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE><C6AC>̨<CCA8><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : rejectReason
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Recipe.Models;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipUnloadActivity : ActivityAbstractBase
|
||||
{
|
||||
private readonly TimeSpan _timeout;
|
||||
|
||||
public ChipUnloadActivity(string name, TimeSpan? timeout = null)
|
||||
: base(name)
|
||||
{
|
||||
_timeout = timeout ?? TimeSpan.FromSeconds(30);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
activityControl.ThrowIfCancellationRequested();
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
CurrentChipStateService currentChipStateService;
|
||||
if (!context.TryGetData<CurrentChipStateService>(WorkflowContextKeys.CurrentChipStateService, out currentChipStateService) || currentChipStateService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>ǰоƬ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
AutoProductionRuntimeStateService autoProductionRuntimeStateService;
|
||||
if (!context.TryGetData<AutoProductionRuntimeStateService>(WorkflowContextKeys.AutoProductionRuntimeStateService, out autoProductionRuntimeStateService) || autoProductionRuntimeStateService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
if (currentChipStateService.CurrentState == CurrentChipLifecycleState.Empty)
|
||||
{
|
||||
autoProductionRuntimeStateService.SetCurrentChipRemainingCount(0);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Empty);
|
||||
context.SetData(WorkflowContextKeys.PendingChipLoad, true);
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipRemainingCount, autoProductionRuntimeStateService.CurrentChipRemainingCount);
|
||||
return ActivityResult.Success;
|
||||
}
|
||||
|
||||
currentChipStateService.SetState(CurrentChipLifecycleState.Unloading);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Unloading);
|
||||
|
||||
ChipPreparationRequest request = new ChipPreparationRequest
|
||||
{
|
||||
RecipeName = ResolveRecipeName(context),
|
||||
Action = ChipPreparationAction.Unload,
|
||||
SourceStepId = ResolveSourceStepId(context)
|
||||
};
|
||||
|
||||
string rejectReason;
|
||||
if (!preparationAreaService.TryRequestPrepare(request, out rejectReason))
|
||||
{
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : rejectReason
|
||||
});
|
||||
}
|
||||
|
||||
ChipPreparationWaitResult waitResult = await preparationAreaService.WaitUntilReadyAsync(_timeout, activityControl.CancellationToken).ConfigureAwait(false);
|
||||
if (!waitResult.Success)
|
||||
{
|
||||
if (waitResult.IsCanceled)
|
||||
{
|
||||
SetWorkflowFailure(context, string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "оƬ<D0BE><C6AC><EFBFBD>ϵȴ<CFB5><C8B4><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>" : waitResult.ErrorMessage);
|
||||
return ActivityResult.Canceled;
|
||||
}
|
||||
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "оƬ<D0BE><C6AC><EFBFBD>ϵȴ<CFB5>ʧ<EFBFBD>ܡ<EFBFBD>" : waitResult.ErrorMessage
|
||||
});
|
||||
}
|
||||
|
||||
if (!preparationAreaService.TryConsumeReady(out rejectReason))
|
||||
{
|
||||
return Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE><C6AC><EFBFBD>Ͻ<EFBFBD><CFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : rejectReason
|
||||
});
|
||||
}
|
||||
|
||||
currentChipStateService.SetState(CurrentChipLifecycleState.Empty);
|
||||
autoProductionRuntimeStateService.SetCurrentChipRemainingCount(0);
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Empty);
|
||||
context.SetData(WorkflowContextKeys.PendingChipLoad, true);
|
||||
context.SetData(WorkflowContextKeys.CurrentChipRemainingCount, autoProductionRuntimeStateService.CurrentChipRemainingCount);
|
||||
return ActivityResult.Success;
|
||||
}
|
||||
|
||||
private static string ResolveRecipeName(WorkflowContext context)
|
||||
{
|
||||
RecipeManager recipeManager;
|
||||
if (context.TryGetData<RecipeManager>(WorkflowContextKeys.RecipeManager, out recipeManager) &&
|
||||
recipeManager != null &&
|
||||
recipeManager.CurrentWaferRecipe != null)
|
||||
{
|
||||
return recipeManager.CurrentWaferRecipe.RecipeName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string ResolveSourceStepId(WorkflowContext context)
|
||||
{
|
||||
string stepId;
|
||||
if (context.TryGetData<string>(WorkflowContextKeys.CurrentStepId, out stepId))
|
||||
{
|
||||
return stepId;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Recipe.Models;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class ChipUnloadRequestActivity : ActivityAbstractBase
|
||||
{
|
||||
public ChipUnloadRequestActivity(string name, TimeSpan? timeout = null) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
activityControl.ThrowIfCancellationRequested();
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
ChipPreparationRequest request = new ChipPreparationRequest
|
||||
{
|
||||
RecipeName = ResolveRecipeName(context),
|
||||
Action = ChipPreparationAction.Unload,
|
||||
SourceStepId = ResolveSourceStepId(context)
|
||||
};
|
||||
|
||||
string rejectReason;
|
||||
if (preparationAreaService.TryRequestPrepare(request, out rejectReason))
|
||||
{
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
return Task.FromResult(Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<D0BE><C6AC>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܾ<F3B1BBBE><DCBE><EFBFBD>" : rejectReason
|
||||
}));
|
||||
}
|
||||
|
||||
private static string ResolveRecipeName(WorkflowContext context)
|
||||
{
|
||||
if (context.TryGetData<RecipeManager>(WorkflowContextKeys.RecipeManager, out var recipeManager) &&
|
||||
recipeManager != null &&
|
||||
recipeManager.CurrentWaferRecipe != null)
|
||||
{
|
||||
return recipeManager.CurrentWaferRecipe.RecipeName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string ResolveSourceStepId(WorkflowContext context)
|
||||
{
|
||||
if (context.TryGetData<string>(WorkflowContextKeys.CurrentStepId, out var stepId))
|
||||
{
|
||||
return stepId;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using MainShell.ProcessResult;
|
||||
using System;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class CurrentChipStateService
|
||||
{
|
||||
private readonly ProcessResultManager _processResultManager;
|
||||
private CurrentChipLifecycleState _currentState;
|
||||
|
||||
public CurrentChipStateService(ProcessResultManager processResultManager)
|
||||
{
|
||||
_processResultManager = processResultManager ?? throw new ArgumentNullException(nameof(processResultManager));
|
||||
_currentState = _processResultManager.CurrentChipState.State;
|
||||
}
|
||||
|
||||
public CurrentChipLifecycleState CurrentState
|
||||
{
|
||||
get { return _currentState; }
|
||||
}
|
||||
|
||||
public void SetState(CurrentChipLifecycleState chipState)
|
||||
{
|
||||
_currentState = chipState;
|
||||
_processResultManager.SaveCurrentChipState(chipState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class PreparationAreaService
|
||||
{
|
||||
private readonly IChipPreparationService _innerService;
|
||||
|
||||
public PreparationAreaService(IChipPreparationService innerService)
|
||||
{
|
||||
_innerService = innerService ?? throw new ArgumentNullException(nameof(innerService));
|
||||
}
|
||||
|
||||
public IChipPreparationService InnerService
|
||||
{
|
||||
get { return _innerService; }
|
||||
}
|
||||
|
||||
public ChipPreparationStatus CurrentStatus
|
||||
{
|
||||
get { return _innerService.Current.Status; }
|
||||
}
|
||||
|
||||
public bool TryRequestPrepare(ChipPreparationRequest request, out string rejectReason)
|
||||
{
|
||||
return _innerService.TryRequestPrepare(request, out rejectReason);
|
||||
}
|
||||
|
||||
public Task<ChipPreparationWaitResult> WaitUntilReadyAsync(TimeSpan timeout, CancellationToken cancellationToken)
|
||||
{
|
||||
return _innerService.WaitUntilReadyAsync(timeout, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<ChipPreparationWaitResult> WaitUntilLoadedAsync(TimeSpan timeout, CancellationToken cancellationToken)
|
||||
{
|
||||
return _innerService.WaitUntilLoadedAsync(timeout, cancellationToken);
|
||||
}
|
||||
|
||||
public bool TryConsumeReady(out string rejectReason)
|
||||
{
|
||||
return _innerService.TryConsumeReady(out rejectReason);
|
||||
}
|
||||
|
||||
public Task CancelAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return _innerService.CancelAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
_innerService.Pause();
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
_innerService.Resume();
|
||||
}
|
||||
|
||||
public bool TryMarkReady(string requestId, out string rejectReason)
|
||||
{
|
||||
return _innerService.TryMarkReady(requestId, out rejectReason);
|
||||
}
|
||||
|
||||
public bool TryMarkFault(string errorMessage, out string rejectReason)
|
||||
{
|
||||
return _innerService.TryMarkFault(errorMessage, out rejectReason);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Recipe.Models;
|
||||
using MW.WorkFlow;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class PreparationSignalActivity : ActivityAbstractBase
|
||||
{
|
||||
public PreparationSignalActivity(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
||||
{
|
||||
activityControl.ThrowIfCancellationRequested();
|
||||
|
||||
bool pendingChipLoad;
|
||||
if (context.TryGetData<bool>(WorkflowContextKeys.PendingChipLoad, out pendingChipLoad) && !pendingChipLoad)
|
||||
{
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
PreparationAreaService preparationAreaService;
|
||||
if (!context.TryGetData<PreparationAreaService>(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null)
|
||||
{
|
||||
throw new InvalidOperationException("δ<>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
ChipPreparationRequest request = new ChipPreparationRequest
|
||||
{
|
||||
RecipeName = ResolveRecipeName(context),
|
||||
Action = ChipPreparationAction.Prepare,
|
||||
SourceStepId = ResolveSourceStepId(context)
|
||||
};
|
||||
|
||||
string rejectReason;
|
||||
if (preparationAreaService.TryRequestPrepare(request, out rejectReason) || CanIgnoreReject(preparationAreaService))
|
||||
{
|
||||
context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus);
|
||||
return Task.FromResult(ActivityResult.Success);
|
||||
}
|
||||
|
||||
return Task.FromResult(Fail(
|
||||
context,
|
||||
MessageKey.ProcessStepFailedWithReason,
|
||||
new object[]
|
||||
{
|
||||
Name,
|
||||
string.IsNullOrWhiteSpace(rejectReason) ? "оƬ<C6AC><D7BC><EFBFBD>źŴ<C5BA><C5B4><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>" : rejectReason
|
||||
}));
|
||||
}
|
||||
|
||||
private static bool CanIgnoreReject(PreparationAreaService preparationAreaService)
|
||||
{
|
||||
return preparationAreaService.CurrentStatus == ChipPreparationStatus.Preparing ||
|
||||
preparationAreaService.CurrentStatus == ChipPreparationStatus.Prepared ||
|
||||
preparationAreaService.CurrentStatus == ChipPreparationStatus.Loading ||
|
||||
preparationAreaService.CurrentStatus == ChipPreparationStatus.Loaded;
|
||||
}
|
||||
|
||||
private static string ResolveRecipeName(WorkflowContext context)
|
||||
{
|
||||
RecipeManager recipeManager;
|
||||
if (context.TryGetData<RecipeManager>(WorkflowContextKeys.RecipeManager, out recipeManager) &&
|
||||
recipeManager != null &&
|
||||
recipeManager.CurrentWaferRecipe != null)
|
||||
{
|
||||
return recipeManager.CurrentWaferRecipe.RecipeName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string ResolveSourceStepId(WorkflowContext context)
|
||||
{
|
||||
string stepId;
|
||||
if (context.TryGetData<string>(WorkflowContextKeys.CurrentStepId, out stepId))
|
||||
{
|
||||
return stepId;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user