@ -1,7 +1,7 @@
package a8k.app.service.mainctrl.mainflowctrl.action ;
import a8k.OS ;
import a8k.app.a8ktype.device.* ;
import a8k.app.factory.AppErrorFactory ;
import a8k.app.service.lowerctrl.* ;
import a8k.app.service.mainctrl.mainflowctrl.base.* ;
import a8k.app.service.statemgr.IncubationPlateStateMgrService ;
@ -11,7 +11,7 @@ import a8k.app.a8ktype.state.ProjectTaskContext;
import a8k.app.a8ktype.state.Tube ;
import a8k.app.a8ktype.state.TubeHolder ;
import a8k.app.a8ktype.state.enumtype.TubeState ;
import a8k.app.service.mainctrl.erroranalyzer.ErrorAnalyze r ;
import a8k.app.service.mainctrl.erroranalyzer.ErrorProcesso r ;
import a8k.app.dao.db.type.a8kidcard.zenum.A8kReactionFlowType ;
import a8k.app.utils.ActionTaskPool ;
import a8k.teststate.VirtualDevice ;
@ -27,7 +27,6 @@ import org.springframework.util.Assert;
import java.util.ArrayList ;
import java.util.List ;
import java.util.Objects ;
import java.util.concurrent.* ;
@Component
@MainFlowProcesser
@ -64,6 +63,7 @@ public class AC41ProcessSample extends A8kActionTask {
/ /
ActionTaskPool actionTaskPool = new ActionTaskPool ( 3 ) ;
List < AppError > errorsCollection = new ArrayList < > ( ) ;
BoolCondition reactionPlateReadyCondition = actionTaskPool . createBoolCondition ( "ReactionPlateReady" ) ;
BoolCondition sampleIsReadyCondition = actionTaskPool . createBoolCondition ( "SampleIsReady" ) ;
@ -101,43 +101,15 @@ public class AC41ProcessSample extends A8kActionTask {
} else {
startTask ( ) ;
}
return afterDoAction ( a ctionTaskPool . waitAllDone ( ) ) ;
return actionTaskPool . waitAllDone ( ) ;
}
/ * *
* 动作处理完成后的处理 ( 串行 ) , 一般用于修改状态
* /
private List < AppError > afterDoAction ( List < AppError > errors ) {
Tube tube = tubeStateMgrService . getCurProcessingTube ( ) ;
List < ProjectTaskContext > ctxs = projectContextMgrService . findCxts ( tube . getSampleId ( ) ) ;
/ / 如果存在致命错误 , 则直接结束
if ( ! errors . isEmpty ( ) & & ErrorAnalyzer . isContainFatalError ( errors ) ) {
tubeStateMgrService . changeTubeStateToError ( errors ) ;
for ( ProjectTaskContext cxt : ctxs ) {
incubationPlateStateMgrService . setIncubationToErrorState ( cxt . getIncubatorPos ( ) , errors ) ;
}
return errors ;
}
/ / 如果存在非致命错误 , 则只是将相关的试管打上错误的标记
if ( ! errors . isEmpty ( ) ) {
tubeStateMgrService . changeTubeStateToError ( errors ) ;
for ( ProjectTaskContext cxt : ctxs ) {
incubationPlateStateMgrService . setIncubationToErrorState ( cxt . getIncubatorPos ( ) , errors ) ;
}
return new ArrayList < > ( ) ;
}
/ / 正常处理
for ( ProjectTaskContext cxt : ctxs ) {
incubationPlateStateMgrService . syncSampleInfo ( cxt . getIncubatorPos ( ) , Objects . requireNonNull ( ProjInfoUtils . buildProjBrefInfo ( cxt ) ) , cxt . getSampleInfo ( ) ) ;
incubationPlateStateMgrService . startIncubating ( cxt . getIncubatorPos ( ) , cxt . getStartIncubatedTime ( ) , cxt . getIncubatedTimeSec ( ) ) ;
}
tubeStateMgrService . changeTubeStateToProcessed ( ) ;
return new ArrayList < > ( ) ;
}
/ / private List < AppError > afterDoAction ( List < AppError > errors ) {
/ / / / ! ! ! tubeStateMgrService . changeTubeStateToError ( errors ) ;
/ / }
/ /
@ -145,7 +117,7 @@ public class AC41ProcessSample extends A8kActionTask {
/ /
void startVirtualTask ( ) {
actionTaskPool . pushTask ( "samplePrepare" , new ActionTaskPool . ActionTask ( ) {
actionTaskPool . pushTask ( "samplePrepareAndRecyle " , new ActionTaskPool . ActionTask ( ) {
@Override public void doAction ( ) throws AppException , ZAppInterruptException {
}
@ -154,6 +126,10 @@ public class AC41ProcessSample extends A8kActionTask {
return null ;
}
@Override public void rollback ( ) throws AppException {
}
} ) ;
actionTaskPool . pushTask ( "paltePrepare" , new ActionTaskPool . ActionTask ( ) {
@ -165,6 +141,9 @@ public class AC41ProcessSample extends A8kActionTask {
return null ;
}
@Override public void rollback ( ) throws AppException {
}
} ) ;
@ -175,14 +154,16 @@ public class AC41ProcessSample extends A8kActionTask {
@Override public Exception processError ( Exception e ) {
return null ;
}
@Override public void rollback ( ) throws AppException {
}
} ) ;
}
void startTask ( ) {
actionTaskPool . pushTask ( "samplePrepare" , new ActionTaskPool . ActionTask ( ) {
actionTaskPool . pushTask ( "samplePrepareAndRecyle" , new ActionTaskPool . ActionTask ( ) {
@Override public void doAction ( ) throws AppException , ZAppInterruptException {
Tube tube = tubeStateMgrService . getCurProcessingTube ( ) ;
TubeHolder tubeHolder = tubeStateMgrService . getTubeHolder ( ) ;
@ -212,20 +193,17 @@ public class AC41ProcessSample extends A8kActionTask {
/ / 等待样本处理完成 wait condition isReady
sampleProcessFinishedCondition . waitTrue ( ) ;
/ / 样本后处理
tubePreProcesCtrlService . resteModule ( ) ;
}
@Override public Exception processError ( Exception e ) throws AppException {
/ *
* 该阶段遇到异常基本上是硬件异常 , 无法被处理
* /
if ( e instanceof ZAppInterruptException ) {
tubePreProcesCtrlService . resteModule ( ) ;
return null ;
@Override public Exception processError ( Exception e ) {
return processException ( e ) ;
}
return e ;
/ / when error , rollback
@Override public void rollback ( ) throws AppException {
tubePreProcesCtrlService . resteModule ( ) ;
}
} ) ;
@ -248,81 +226,91 @@ public class AC41ProcessSample extends A8kActionTask {
}
@Override public Exception processError ( Exception e ) {
return processException ( e ) ;
}
if ( e instanceof ZAppInterruptException ) {
/ / when error , rollback
@Override public void rollback ( ) throws AppException {
/ /
/ / 清空孵育盘中反应板
/ /
Tube tube = tubeStateMgrService . getCurProcessingTube ( ) ;
List < ProjectTaskContext > cxts = projectContextMgrService . findCxts ( tube . getSampleId ( ) ) ;
for ( ProjectTaskContext cxt : cxts ) {
IncubatorPos incubatorPos = cxt . getIncubatorPos ( ) ;
/ / plateBoxCtrlService . pushPlateQuick ( cxt . getConsumable ( ) . getGroup ( ) , incubatorPos ) ;
/ / plateBoxCtrlService . resetIncubatorPos ( )
/ / 丢弃反应板
optScanModuleCtrlService . pullPlate ( incubatorPos ) ;
optScanModuleCtrlService . dropPlate ( ) ;
/ / 重置孵育盘位置状态
incubationPlateStateMgrService . resetIncubatorPos ( incubatorPos ) ;
}
}
return null ;
}
} ) ;
actionTaskPool . pushTask ( "sampleProcess" , new ActionTaskPool . ActionTask ( ) {
@Override public void doAction ( ) throws AppException , ZAppInterruptException {
/ /
/ / 取样本到小缓冲瓶或者探测物质中进行反应
/ /
Tube tube = tubeStateMgrService . getCurProcessingTube ( ) ;
List < ProjectTaskContext > cxts = projectContextMgrService . findCxts ( tube . getSampleId ( ) ) ;
Assert . isTrue ( ! cxts . isEmpty ( ) , "项目上下文不能为空" ) ;
/ / 反应液准备
for ( ProjectTaskContext cxt : cxts ) {
preProcessSample ( cxt ) ;
}
@Override public Exception processError ( Exception e ) {
return null ;
}
/ / ! 等待样本准备完成
sampleIsReadyCondition . waitTrue ( ) ;
} ) ;
for ( ProjectTaskContext cxt : cxts ) {
Boolean cxtIsFinal = cxt . equals ( cxts . get ( cxts . size ( ) - 1 ) ) ;
doSampleProcess ( cxt , cxtIsFinal ) ;
}
/ * *
* 样本准备
* 1 . 脱帽 , 盖帽 , 摇匀
* 2 . 恢复模组
* @throws AppException e
* @throws ZAppInterruptException e
* /
void samplePrepare ( ) throws AppException , ZAppInterruptException {
/ / 样本使用完 , 可以回收了
sampleProcessFinishedCondition . setReady ( ) ;
}
/ * *
* 反应板准备
* 1 . 推入反应板到赋予盘
* @throws AppException e
* @throws ZAppInterruptException e
* /
void paltePrepare ( ) throws AppException , ZAppInterruptException {
Tube tube = tubeStateMgrService . getCurProcessingTube ( ) ;
List < ProjectTaskContext > cxts = projectContextMgrService . findCxts ( tube . getSampleId ( ) ) ;
for ( ProjectTaskContext cxt : cxts ) {
IncubatorPos incubatorPos = cxt . getIncubatorPos ( ) ;
@Override public Exception processError ( Exception e ) {
return processException ( e ) ;
}
plateBoxCtrlService . pushPlateQuick ( cxt . getConsumable ( ) . getGroup ( ) , incubatorPos ) ;
@Override public void rollback ( ) throws AppException {
/ /
reactionPlateReadyCondition . setReady ( ) ;
}
} ) ;
}
void sampleProcess ( ) throws AppException , ZAppInterruptException {
Tube tube = tubeStateMgrService . getCurProcessingTube ( ) ;
Exception processException ( Exception e ) {
if ( e instanceof ZAppInterruptException ) {
return null ;
} else if ( ! ErrorProcessor . isFatalException ( e ) ) {
errorsCollection . add ( AppErrorFactory . exceptionToAppError ( e ) ) ;
return null ;
} else {
errorsCollection . add ( AppErrorFactory . exceptionToAppError ( e ) ) ;
return e ;
}
}
/ / 准备第一个项目的tip头
List < ProjectTaskContext > cxts = projectContextMgrService . findCxts ( tube . getSampleId ( ) ) ;
Assert . isTrue ( ! cxts . isEmpty ( ) , "项目上下文不能为空" ) ;
void preProcessSample ( ProjectTaskContext cxt ) throws AppException , ZAppInterruptException {
/ / 取探测物质
A8kReactionFlowType type = cxt . getProjBuildinInfo ( ) . reactionFlowType ;
liquidOperationCtrlService . setProjContext ( cxt . projBuildinInfo , cxt . projExtInfoCard ) ;
for ( ProjectTaskContext cxt : cxts ) {
/ /
/ / 取样本到小缓冲瓶
/ /
if ( type . equals ( A8kReactionFlowType . SampleAndBS ) ) {
Boolean cxtIsFinal = cxt . equals ( cxts . get ( cxts . size ( ) - 1 ) ) ;
doSampleProcess ( cxt , cxtIsFinal ) ;
} else if ( type . equals ( A8kReactionFlowType . SampleAndBSAndProbeSubstance ) ) {
log . info ( "取大瓶缓冲液" ) ;
liquidOperationCtrlService . takeLargeBottleBufferLiquidToProbeSubstance ( / /
cxt . getLargeBufferPos ( ) , cxt . getPreReactionPos ( ) , cxt . getTakeLargeBSVolume ( ) ) ;
}
sampleProcessFinishedCondition . setReady ( ) ;
}
/ * *
@ -340,11 +328,11 @@ public class AC41ProcessSample extends A8kActionTask {
* @throws AppException e
* @throws ZAppInterruptException e
* /
void doSampleProcess ( ProjectTaskContext cxt , Boolean finalCxt ) throws AppException , ZAppInterruptException {
log . info ( "开始处理样本 cxtid:{} sampleId:{}" , cxt . cxtId , cxt . sampleInfo . sampleId ) ;
A8kReactionFlowType type = cxt . getProjBuildinInfo ( ) . reactionFlowType ;
liquidOperationCtrlService . setProjContext ( cxt . projBuildinInfo , cxt . projExtInfoCard ) ;
/ / ! ! ! 等待样本准备完成 ! ! !
/ /
/ / 取样本到小缓冲瓶
@ -352,30 +340,14 @@ public class AC41ProcessSample extends A8kActionTask {
if ( type . equals ( A8kReactionFlowType . SampleAndBS ) ) {
log . info ( "FlowType1:" ) ;
log . info ( " FlowType1->刺破小缓冲瓶" ) ;
liquidOperationCtrlService . pirceLittleBuffer ( cxt . getPreReactionPos ( ) ) ;
/ / ! ! ! 等待样本准备完成 ! ! !
sampleIsReadyCondition . waitTrue ( ) ;
/ / 取样
log . info ( " FlowType1->取样" ) ;
liquidOperationCtrlService . takeSample ( cxt . getSamplePos ( ) , cxt . getPreReactionPos ( ) , cxt . getSampleVol ( ) ) ;
} else if ( type . equals ( A8kReactionFlowType . SampleAndBSAndProbeSubstance ) ) {
log . info ( "FlowType2:" ) ;
/ / 取大瓶缓冲液
log . info ( " FlowType2->取大瓶缓冲液" ) ;
liquidOperationCtrlService . takeLargeBottleBufferLiquidToProbeSubstance ( / /
cxt . getLargeBufferPos ( ) , cxt . getPreReactionPos ( ) , cxt . getTakeLargeBSVolume ( ) ) ;
/ / ! ! ! 等待样本准备完成 ! ! !
sampleIsReadyCondition . waitTrue ( ) ;
/ / 取样
log . info ( " FlowType2->取样" ) ;
liquidOperationCtrlService . takeSample ( cxt . getSamplePos ( ) , cxt . getPreReactionPos ( ) , cxt . getSampleVol ( ) ) ;
}
@ -385,82 +357,28 @@ public class AC41ProcessSample extends A8kActionTask {
sampleProcessFinishedCondition . setReady ( ) ;
}
/ /
/ / 取初步反应混合液到反应板
/ /
/ / ! 等待反应板准备完成
reactionPlateReadyCondition . waitTrue ( ) ;
turnableMoveCtrlService . trunableMoveToDropLiquidPos ( cxt . getIncubatorPos ( ) ) ; / / 孵育盘移动到吐液位置
liquidOperationCtrlService . takePreReactionLiquidToLiquid ( cxt . getPreReactionPos ( ) ) ; / / 取反应液到反应板上
/ / 孵育
cxt . setStartIncubatedTime ( System . currentTimeMillis ( ) ) ;
cxt . setIncubatedTimeSec ( cxt . getProjBuildinInfo ( ) . reactionPlateIncubationTimeMin * 60 ) ;
incubationPlateStateMgrService . syncSampleInfo ( cxt . getIncubatorPos ( ) , Objects . requireNonNull ( ProjInfoUtils . buildProjBrefInfo ( cxt ) ) , cxt . getSampleInfo ( ) ) ;
incubationPlateStateMgrService . startIncubating ( cxt . getIncubatorPos ( ) , cxt . getStartIncubatedTime ( ) , cxt . getIncubatedTimeSec ( ) ) ;
}
/ /
/ / UTILS
/ / 异常由各个Action自行进行处理 , 返回给上层 , 则认为是无法处理的异常 , 直接结束
/ /
List < AppError > wait ( List < Future < AppError > > futures ) {
for ( var future : futures ) {
while ( ! future . isDone ( ) ) {
OS . forceSleep ( 100 ) ;
}
}
List < AppError > errors = new ArrayList < > ( ) ;
for ( var future : futures ) {
try {
errors . add ( future . get ( ) ) ;
} catch ( InterruptedException | ExecutionException ignored ) {
}
}
errors . removeIf ( Objects : : isNull ) ;
return errors ;
}
/ / Future < AppError > doActionTask ( String actionTaskMarker , ActionTask actionTask ) {
/ / return executor . submit ( ( ) - > {
/ / AppError error = null ;
/ / String oldName = Thread . currentThread ( ) . getName ( ) ;
/ / try {
/ / Thread . currentThread ( ) . setName ( this . getClass ( ) . getName ( ) + actionTaskMarker ) ;
/ / actionTask . call ( ) ;
/ / log . info ( "Line {} 执行完成" , actionTaskMarker ) ;
/ / } catch ( AppException e ) {
/ / reactionPlateReady . interrupt ( ) ;
/ / sampleIsReady . interrupt ( ) ;
/ / sampleProcessFinished . interrupt ( ) ;
/ / log . error ( "{} catch 异常" , actionTaskMarker , e ) ;
/ / error = e . error ;
/ / } catch ( ZAppInterruptException ignored ) {
/ / log . warn ( "{} catch 中断" , actionTaskMarker ) ;
/ / } catch ( Exception e ) {
/ / log . error ( "{} catch 异常" , actionTaskMarker , e ) ;
/ / error = new AECodeError ( e ) ;
/ / }
/ / Thread . currentThread ( ) . setName ( oldName ) ;
/ / return error ;
/ / } ) ;
/ / }
/ *
* 逻辑 :
* 处理 - - > 发生异常 - - - > ( 其他线程自动在指定位置结束动作 )
*
* - - - > 后处理 ( 机械结构归位 , 试管归位 )
* - - - > 异常处理
*
* doAction
* startWork ( work , errorProcess , afterWork )
* startWork ( work , errorProcess , afterWork )
* startWork ( work , errorProcess , afterWork )
*
* waitForAllDone
* return remainingErrors
*
* /
}