public bool StartJob(string jobName, Dictionary<int, NMC.Scheduling.Route> routes, string src, string dest, int cycleNum, string mode, bool isProcess, bool isUnload, bool isHigh, string runID, Dictionary<string, string> preProcesses, string category, ref string err)
{
try
{
err = "";
bool needCool = false;
foreach (KeyValuePair<int, NMC.Scheduling.Route> kvp in routes)
{
this.GetLogger().WarnFormat("Slot{{0}}: Route({1})", kvp.Key, kvp.Value.Name);
for (int i = 0; i < kvp.Value.GetStepNum(); ++i)
{
this.GetLogger().WarnFormat(" Step({0})", i);
bool containCoolingChamber = false;
bool allCoolingChamberOK = true;
for (int j = 0; j < kvp.Value.RouteSteps[i].GetVisitNum(); ++j)
{
this.GetLogger().WarnFormat(" Visit({0}).StationName: {1}", j, kvp.Value.RouteSteps[i].GetVisit(j).StationName);
this.GetLogger().WarnFormat(" Visit({0}).SlotID: {1}", j, kvp.Value.RouteSteps[i].GetVisit(j).SlotID);
this.GetLogger().WarnFormat(" Visit({0}).ProcessRecipe: {1}", j, kvp.Value.RouteSteps[i].GetVisit(j).ProcessRecipe);
if (!string.IsNullOrEmpty(kvp.Value.RouteSteps[i].GetVisit(j).ProcessRecipe))
{
this.mCtrlNodes[this.mUniqueCtrlNode].GetRecipeInfo("SCOPE", kvp.Value.RouteSteps[i].GetVisit(j).ProcessRecipe); // RemoteOperationException, yangy 20170605: check recipe exist or not
}
// <><><> yangy: add 'else' check ??? post alarm when no process recipe attached <><><>
// xianghf_20191015, for CXMT: wafer need be cool down before move to LL
// when ChA/ChB were set as cooling chamber, but no recipe is linked to ChA where ChA parallel with ChB in sequence
//
if (this.mCoolingChkEnabled)
{
if (this.mHighTempModules.Contains(kvp.Value.RouteSteps[i].GetVisit(j).StationName))
{
needCool = true; // 并行chamber中任意一chamber为high, 则设置needCool为true
}
if (this.mCoolingModules.Contains(kvp.Value.RouteSteps[i].GetVisit(j).StationName)) //&& !string.IsNullOrEmpty(kvp.Value.RouteSteps[i].GetVisit(j).ProcessRecipe))
{
containCoolingChamber = true;
for (int p = 0; p < kvp.Value.RouteSteps[i].GetVisitNum(); ++p)
{
if (!this.mCoolingModules.Contains(kvp.Value.RouteSteps[i].GetVisit(p).StationName))
{
allCoolingChamberOK = false;
break;
}
else if (string.IsNullOrEmpty(kvp.Value.RouteSteps[i].GetVisit(p).ProcessRecipe))
{
allCoolingChamberOK = false;
break;
}
}
}
}
}
if (this.mCoolingChkEnabled)
{
// 并行chamber中所有cooling chamber必须link recipe
if (containCoolingChamber && allCoolingChamberOK)
{
needCool = false;
}
}
}
if (needCool)
{
this.GetLogger().ErrorFormat("Coordinator::StartJob(): There is NO cooling recipe in job '{0}'.", jobName);
#if SCOPE_LANG_CH
{
err = string.Format("任务 '{0}' 中缺少冷却工艺步骤!", jobName);
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("'{2}'关联的任务'{0}[{1}]'启动失败!", jobName, runID, src), err);
}
#else
{
err = string.Format("There is NO cooling recipe in job '{0}'.", jobName);
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
}
#endif
// AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
return false;
}
}
// <><><> check dup base on 'jobName'
if (TaskManager.GetIns().GetTaskID(jobName) > 0)
{
this.GetLogger().ErrorFormat("Coordinator::StartJob(): Job named '{0}' has been existed.", jobName);
#if SCOPE_LANG_CH
{
err = string.Format("任务 '{0}' 已经存在!", jobName);
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("'{2}'关联的任务'{0}[{1}]'启动失败!", jobName, runID, src), err);
}
#else
{
err = string.Format("Job '{0}' has been existed.", jobName);
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
}
#endif
//err = string.Format("Job '{0}' has been existed.", jobName);
//AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
return false;
}
if (TaskManager.GetIns().IsOverridePreJob(src, routes))
{
this.GetLogger().ErrorFormat("Coordinator::StartJob(): Job named '{0}' overrides the previous job.", jobName);
#if SCOPE_LANG_CH
{
err = string.Format("任务 '{0}'与已其它任务有重合!", jobName);
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("'{2}'关联的任务'{0}[{1}]'启动失败!", jobName, runID, src), err);
}
#else
{
err = string.Format("Job '{0}' overrides the previous job.", jobName);
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
}
#endif
//err = string.Format("Job '{0}' overrides the previous job.", jobName);
//AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
return false;
}
}
catch (Exception ex)
{
this.GetLogger().ErrorFormat("Coordinator::StartJob(): {0}", ex.Message);
err = ex.Message;
#if SCOPE_LANG_CH
{
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("'{2}'关联的任务'{0}[{1}]'启动失败!", jobName, runID, src), err);
}
#else
{
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
}
#endif
//AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
return false;
}
// <><> yangy 20160505: add Time Synchronizer check
////
try
{
if (TimeSynchronizer.GetIns().CriticalZoneBegin(ref err))
{
return TaskManager.GetIns().StartTask(new Job(jobName, routes, src, dest, cycleNum, (JobMode)Enum.Parse(typeof(JobMode), mode), isProcess, isUnload, isHigh, runID, preProcesses, "", category));
}
return false;
}
catch (Exception ex)
{
this.GetLogger().ErrorFormat("Coordinator::StartJob(): {0}", ex.Message);
#if SCOPE_LANG_CH
{
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("'{2}'关联的任务'{0}[{1}]'启动失败!", jobName, runID, src), err);
}
#else
{
AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
}
#endif
//err = ex.Message;
//AlarmManager.GetIns().PostAlarmAndForget(string.Format("{0}[{1}]", jobName, runID), AlarmType.StartJobFailed, string.Format("Start job '{0}[{1}]' on '{2}' failed!", jobName, runID, src), err);
return false;
}
finally
{
TimeSynchronizer.GetIns().CriticalZoneEnd();
}
}