zhourui пре 5 година
родитељ
комит
2078b3c35b
41 измењених фајлова са 1617 додато и 703 уклоњено
  1. 0 175
      o2server/configSample/node.json
  2. 5 1
      o2server/configSample/processPlatform.json
  3. 55 61
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ProcessPlatform.java
  4. 0 56
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/executor/Signal.java
  5. 1 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_processplatform_service_processing.java
  6. 2 0
      o2server/x_console/src/main/java/com/x/server/console/action/EraseContentLog.java
  7. 2 0
      o2server/x_console/src/main/java/com/x/server/console/action/EraseContentProcessPlatform.java
  8. 149 152
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/ActionProcessing.java
  9. 9 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/ProcessingRunnableImpl.java
  10. 2 2
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/PersistenceProperties.java
  11. 0 8
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/content/Work.java
  12. 42 3
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/Manual.java
  13. 19 0
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/ManualProperties.java
  14. 0 105
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/ProcessingError.java
  15. 841 0
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/Signal.java
  16. 9 0
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/SignalStack.java
  17. 123 0
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/SignalStackLog.java
  18. 23 0
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/SignalStackLogProperties.java
  19. 16 14
      o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/ProcessingAttributes.java
  20. 0 52
      o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/ProcessingSignal.java
  21. 30 0
      o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/service/processing/jaxrs/task/ActionProcessingWo.java
  22. 22 0
      o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/service/processing/jaxrs/work/ActionProcessingSignalWo.java
  23. 20 24
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/Processing.java
  24. 43 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/ProcessingToProcessingSignalStack.java
  25. 7 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/ThisApplication.java
  26. 40 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/ActionProcessingSignal.java
  27. 19 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/WorkAction.java
  28. 7 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/agent/AgentProcessor.java
  29. 24 18
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/begin/BeginProcessor.java
  30. 9 2
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/cancel/CancelProcessor.java
  31. 10 7
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/choice/ChoiceProcessor.java
  32. 7 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/delay/DelayProcessor.java
  33. 8 1
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/embed/EmbedProcessor.java
  34. 8 2
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/end/EndProcessor.java
  35. 7 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/invoke/InvokeProcessor.java
  36. 11 1
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/manual/ManualProcessor.java
  37. 7 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/merge/MergeProcessor.java
  38. 10 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/message/MessageProcessor.java
  39. 11 7
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/parallel/ParallelProcessor.java
  40. 12 6
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/service/ServiceProcessor.java
  41. 7 5
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/split/SplitProcessor.java

+ 0 - 175
o2server/configSample/node.json

@@ -1,175 +0,0 @@
-{
-  "enable": true,
-  "isPrimaryCenter": true,
-  "center": {
-    "enable": true,
-    "order": 0.0,
-    "sslEnable": false,
-    "redeploy": true,
-    "port": 20030.0,
-    "httpProtocol": "",
-    "proxyHost": "",
-    "proxyPort": 20030.0,
-    "scanInterval": 0.0,
-    "configApiEnable": true,
-    "statEnable": true,
-    "statExclusions": "*.js,*.gif,*.jpg,*.png,*.css,*.ico",
-    "maxFormContent": 20.0,
-    "###enable": "是否启用###",
-    "###order": "center节点顺序,顺序排列0,1,2...###",
-    "###sslEnable": "是否启用ssl传输加密,如果启用将使用config/keystore文件作为密钥文件.使用config/token.json文件中的sslKeyStorePassword字段为密钥密码,sslKeyManagerPassword为管理密码.###",
-    "###redeploy": "每次启动是否重新部署所有应用.###",
-    "###port": "端口,center服务器端口,默认20030###",
-    "###httpProtocol": "对外http访问协议,http/https###",
-    "###proxyHost": "代理主机,当服务器是通过apache/nginx等代理服务器映射到公网或者通过路由器做端口映射,在这样的情况下需要设置此地址以标明公网访问地址.###",
-    "###proxyPort": "代理端口,当服务器是通过apache/nginx等代理服务器映射到公网或者通过路由器做端口映射,在这样的情况下需要设置此地址以标明公网访问端口.###",
-    "###scanInterval": "重新扫描war包时间间隔(秒)###",
-    "###config": "其他参数###",
-    "###configApiEnable": "允许通过Api修改config###",
-    "###statEnable": "启用统计,默认启用统计.###",
-    "###statExclusions": "统计忽略路径,默认忽略*.js,*.gif,*.jpg,*.png,*.css,*.ico###",
-    "###maxFormContent": "最大提交数据限制(M),限制有所上传的内容大小,包括附件.###"
-  },
-  "application": {
-    "enable": true,
-    "port": 20020.0,
-    "sslEnable": false,
-    "proxyHost": "",
-    "proxyPort": 20020.0,
-    "redeploy": true,
-    "scanInterval": 0.0,
-    "includes": [],
-    "excludes": [],
-    "weights": [],
-    "scheduleWeights": [],
-    "statEnable": true,
-    "statExclusions": "*.js,*.gif,*.jpg,*.png,*.css,*.ico",
-    "maxFormContent": 20.0,
-    "###enable": "是否启用###",
-    "###port": "http/https端口,负责向前端提供数据访问接口.默认为20020端口.###",
-    "###sslEnable": "是否启用ssl传输加密,如果启用将使用config/keystore文件作为密钥文件.使用config/token.json文件中的sslKeyStorePassword字段为密钥密码,sslKeyManagerPassword为管理密码.###",
-    "###proxyHost": "代理主机,当服务器是通过apache/nginx等代理服务器映射到公网或者通过路由器做端口映射,在这样的情况下需要设置此地址以标明公网访问地址.###",
-    "###proxyPort": "代理端口,当服务器是通过apache/nginx等代理服务器映射到公网或者通过路由器做端口映射,在这样的情况下需要设置此地址以标明公网访问端口.###",
-    "###redeploy": "每次启动是否重载全部应用.###",
-    "###scanInterval": "应用reload扫描间隔,\u003c0 表示不会reload应用,扫描到应用文件发生了变化.###",
-    "###includes": "承载的应用,在集群环境下可以选择仅承载部分应用以降低服务器负载,可以使用*作为通配符.###",
-    "###excludes": "选择不承载的应用,和includes的值配合使用可以选择或者排除承载的应用,可以使用*作为通配符.###",
-    "###weights": "设置应用的Web访问权重,在集群环境中,一个应用可以部署多个实例提供负载均衡.通过合计占比来分配应用占比.###",
-    "###scheduleWeights": "设置应用的定时任务权重,在集群环境中,一个应用可以部署多个实例提供负载均衡.通过合计占比来分配应用占比.###",
-    "###statEnable": "启用统计,默认启用统计.###",
-    "###statExclusions": "统计忽略路径,默认忽略*.js,*.gif,*.jpg,*.png,*.css,*.ico###",
-    "###maxFormContent": "最大提交数据限制(M),限制有所上传的内容大小,包括附件.###"
-  },
-  "web": {
-    "enable": true,
-    "sslEnable": false,
-    "proxyHost": "",
-    "weight": 100.0,
-    "dirAllowed": false,
-    "statEnable": false,
-    "statExclusions": "*.gif,*.jpg,*.png,*.ico",
-    "cacheControlMaxAge": 0.0,
-    "###enable": "是否启用###",
-    "###port": "http/https端口,用户输入网址后实际访问的第一个端口.http协议默认为80端口,https默认为443端口.###",
-    "###sslEnable": "是否启用ssl传输加密,如果启用将使用config/keystore文件作为密钥文件.使用config/token.json文件中的sslKeyStorePassword字段为密钥密码,sslKeyManagerPassword为管理密码.###",
-    "###proxyHost": "代理主机,当服务器是通过apache/nginx等代理服务器映射到公网或者通过路由器做端口映射,在这样的情况下需要设置此地址以标明公网访问地址.###",
-    "###proxyPort": "代理端口,当服务器是通过apache/nginx等代理服务器映射到公网或者通过路由器做端口映射,在这样的情况下需要设置此地址以标明公网访问端口.###",
-    "###weight": "设置权重.当前没有作用,###",
-    "###dirAllowed": "允许浏览目录,###",
-    "###statEnable": "启用统计,默认启用统计.###",
-    "###statExclusions": "统计忽略路径,默认忽略*.gif,*.jpg,*.png,*.ico###",
-    "###cacheControlMaxAge": "服务器max-age缓存时间(秒)###",
-    "###proxyCenterEnable": "是否启用center服务器代理.###",
-    "###proxyApplicationEnable": "是否启用application服务器代理###"
-  },
-  "data": {
-    "enable": true,
-    "tcpPort": 20050.0,
-    "webPort": 20051.0,
-    "includes": [],
-    "excludes": [],
-    "jmxEnable": false,
-    "cacheSize": 512.0,
-    "logLevel": "WARN",
-    "maxTotal": 50.0,
-    "maxIdle": 0.0,
-    "statEnable": true,
-    "statFilter": "mergeStat",
-    "slowSqlMillis": 2000.0,
-    "lockTimeout": 120000.0,
-    "###enable": "是否启用,如果没有可用的externalDataSources.json文件,那么默认会在节点中启用本地的H2数据库作为默认的数据库.###",
-    "###tcpPort": "H2数据库jdbc连接端口,登录的用户名:sa,密码为xadmin的密码.数据库创建在/o2server/local/repository/data/X.mv.db,一旦数据库文件被创建,那么该数据库的密码被创建.###",
-    "###webPort": "H2数据库web端口,H2提供一个web端的client,此端口为web端client的访问端口.用户名sa,密码为xadmin数据库初始创建的密码.###",
-    "###includes": "设置此数据库存储的类,默认情况下存储所有类型,如果需要对每个类进行单独的控制以达到高性能,可以将不同的类存储到不同的节点上提高性能.可以使用通配符*###",
-    "###excludes": "在此节点上不存储的类,和includes一起设置实际存储的类,可以使用通配符*###",
-    "###jmxEnable": "是否启动jmx,如果启用,可以通过本地的jmx客户端进行访问,不支持远程jmx客户端.###",
-    "###cacheSize": "H2数据库缓存大小,设置H2用于作为缓存的内存大小,以M作为单位,这里默认为512M.###",
-    "###logLevel": "默认日志级别###",
-    "###maxTotal": "最大使用连接数###",
-    "###maxIdle": "最大空闲连接数###",
-    "###statEnable": "启用统计,默认启用###",
-    "###statFilter": "统计方式配置,默认mergeStat###",
-    "###slowSqlMillis": "执行缓慢sql毫秒数,默认2000毫秒,执行缓慢的sql将被单独记录.###",
-    "###lockTimeout": "默认锁超时时间()毫秒).###"
-  },
-  "storage": {
-    "enable": true,
-    "port": 20040.0,
-    "sslEnable": false,
-    "name": "251",
-    "accounts": [],
-    "prefix": "",
-    "deepPath": false,
-    "###enable": "是否启用,对于二进制流文件,比如附件,图片等存储在单独的文件服务器中,可以支持多种文件服务器,默认情况下使用ftp服务器作为文件服务器,每个节点可以启动一个文件服务器以提供高性能.###",
-    "###port": "ftp服务器端口,此端口可以不对外开放,仅有ApplicationServer进行访问,并不直接对用户提供服务.###",
-    "###sslEnable": "是否启用ssl传输加密,如果启用将使用config/keystore文件作为密钥文件.使用config/token.json文件中的sslKeyStorePassword字段为密钥密码,sslKeyManagerPassword为管理密码.###",
-    "###name": "名称,多个节点中不能重名,默认为251.###",
-    "###accounts": "二进制流文件是分多个账号分段存储的,可以单独设置每个分类的存储配置,一般不需要设置.###",
-    "###passivePorts": "ftp传输有主动和被动之分,如果使用了被动传输,设置被动端口范围,默认为29000-30000.###",
-    "###prefix": "路径前缀.###",
-    "###deepPath": "使用更深的路径###"
-  },
-  "logLevel": "warn",
-  "dumpData": {
-    "enable": true,
-    "cron": "",
-    "size": 7.0,
-    "path": "",
-    "###enable": "是否启用,默认每天凌晨2点进行备份.###",
-    "###cron": "定时任务cron表达式###",
-    "###size": "最大保留份数,超过将自动删除最久的数据.###",
-    "###path": "备份路径###"
-  },
-  "restoreData": {
-    "enable": false,
-    "cron": "",
-    "path": "",
-    "###enable": "是否启用.###",
-    "###cron": "定时任务cron表达式###",
-    "###path": "恢复路径###"
-  },
-  "nodeAgentEnable": true,
-  "nodeAgentPort": 20010.0,
-  "nodeAgentEncrypt": true,
-  "quickStartWebApp": false,
-  "autoStart": true,
-  "###enable": "是否启用###",
-  "###isPrimaryCenter": "是否是center节点,仅允许存在一个center节点###",
-  "###center": "Center服务器配置###",
-  "###application": "Application服务器配置###",
-  "###web": "Web服务器配置###",
-  "###data": "Data服务器配置###",
-  "###storage": "Storage服务器配置###",
-  "###logLevel": "日志级别,默认当前节点的slf4j日志级别,通过系统变量\"org.slf4j.simpleLogger.defaultLogLevel\"设置到当前jvm中.###",
-  "###dumpData": "定时数据导出配置###",
-  "###restoreData": "定时数据导入配置###",
-  "###logSize": "日志文件保留天数.###",
-  "###auditLogSize": "审计日志文件保留天数.###",
-  "###nodeAgentEnable": "是否启用节点代理###",
-  "###nodeAgentPort": "是否启用节点端口###",
-  "###nodeAgentEncrypt": "是否启用节点代理加密###",
-  "###quickStartWebApp": "是否使用快速应用部署###",
-  "###banner": "服务器控制台启动标识###",
-  "###autoStart": "是否自动启动###",
-  "###eraseContentEnable": "是否允许使用擦除数据功能###"
-}

+ 5 - 1
o2server/configSample/processPlatform.json

@@ -56,6 +56,8 @@
     "###cron": "定时cron表达式###",
     "###thresholdMinutes": "当工作滞留设定时间后,将尝试触发工作流转,可以自动处理由于人员变动的引起的工作滞留,默认24*60分钟.###"
   },
+  "processingSignalThreshold": 1000.0,
+  "processingSignalPersistEnable": false,
   "###maintenanceIdentity": "维护身份,当工作发生意外错误,无法找到对应的处理人情况下,先尝试将工作分配给创建身份,如果创建身份也不可获取,那么分配给指定人员,默认情况下这个值为空.###",
   "###formVersionCount": "表单历史版本保留数量,0为不保留.###",
   "###processVersionCount": "流程历史版本保留数量,0为不保留.###",
@@ -92,5 +94,7 @@
     "###intervalMinutes": "提醒间隔(分钟)###",
     "###count": "提醒数量限制.###"
   },
-  "###extensionEvents": "事件扩充.###"
+  "###extensionEvents": "事件扩充.###",
+  "###processingSignalThreshold": "工作处理异步返回阈值,默认1000毫秒.###",
+  "###processingSignalPersistEnable": "是否保存工作处理信号内容,默认false.###"
 }

+ 55 - 61
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ProcessPlatform.java

@@ -5,16 +5,16 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 
-import com.x.base.core.project.annotation.FieldDescribe;
-import com.x.base.core.project.gson.XGsonBuilder;
-import com.x.base.core.project.tools.DefaultCharset;
-import com.x.base.core.project.tools.ListTools;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.quartz.CronExpression;
 
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.DefaultCharset;
+import com.x.base.core.project.tools.ListTools;
+
 /**
  * @author Zhou Rui
  */
@@ -48,14 +48,17 @@ public class ProcessPlatform extends ConfigObject {
 
 	public static final Boolean DEFAULT_DELETEAPPLICATIONINUSE = false;
 
-	public final static Boolean DEFAULT_UPDATEDATAPROJECTIONENABLE = false;
+	public static final Boolean DEFAULT_UPDATEDATAPROJECTIONENABLE = false;
+
+	public static final Integer DEFAULT_PROCESSINGSIGNALTHRESHOLD = 1000;
+
+	public static final Boolean DEFAULT_PROCESSINGSIGNALPERSISTENABLE = false;
 
 	public static ProcessPlatform defaultInstance() {
 		return new ProcessPlatform();
 	}
 
 	public ProcessPlatform() {
-
 		this.maintenanceIdentity = "";
 		this.formVersionCount = DEFAULT_FORMVERSIONCOUNT;
 		this.processVersionCount = DEFAULT_PROCESSVERSIONCOUNT;
@@ -72,7 +75,8 @@ public class ProcessPlatform extends ConfigObject {
 		this.touchDetained = new TouchDetained();
 		this.deleteDraft = new DeleteDraft();
 		this.passExpired = new PassExpired();
-		this.processingSignal = new ProcessingSignal();
+		this.processingSignalThreshold = DEFAULT_PROCESSINGSIGNALTHRESHOLD;
+		this.processingSignalPersistEnable = DEFAULT_PROCESSINGSIGNALPERSISTENABLE;
 	}
 
 	public Integer getExecutorCount() {
@@ -165,8 +169,25 @@ public class ProcessPlatform extends ConfigObject {
 	@FieldDescribe("事件扩充.")
 	private ExtensionEvents extensionEvents;
 
-	@FieldDescribe("流程处理型号设置.")
-	private ProcessingSignal processingSignal;
+	@FieldDescribe("工作处理异步返回阈值,默认1000毫秒.")
+	private Integer processingSignalThreshold;
+
+	@FieldDescribe("是否保存工作处理信号内容,默认false.")
+	private Boolean processingSignalPersistEnable;
+
+	public Boolean getProcessingSignalPersistEnable() {
+		if (processingSignalPersistEnable == null) {
+			this.processingSignalPersistEnable = DEFAULT_PROCESSINGSIGNALPERSISTENABLE;
+		}
+		return processingSignalPersistEnable;
+	}
+
+	public Integer getProcessingSignalThreshold() {
+		if (processingSignalThreshold == null || processingSignalThreshold < 1) {
+			this.processingSignalThreshold = DEFAULT_PROCESSINGSIGNALTHRESHOLD;
+		}
+		return processingSignalThreshold;
+	}
 
 	public ExtensionEvents getExtensionEvents() {
 		if (null == extensionEvents) {
@@ -215,13 +236,6 @@ public class ProcessPlatform extends ConfigObject {
 		return maintenanceIdentity;
 	}
 
-	public ProcessingSignal getProcessingSignal() {
-		if (this.processingSignal == null) {
-			this.processingSignal = new ProcessingSignal();
-		}
-		return this.processingSignal;
-	}
-
 	public void save() throws Exception {
 		File file = new File(Config.base(), Config.PATH_CONFIG_PROCESSPLATFORM);
 		FileUtils.write(file, XGsonBuilder.toJson(this), DefaultCharset.charset);
@@ -234,9 +248,9 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static Boolean DEFAULT_ENABLE = false;
+		public static final Boolean DEFAULT_ENABLE = false;
 
-		public final static String DEFAULT_CRON = "30 0/10 8-18 * * ?";
+		public static final String DEFAULT_CRON = "30 0/10 8-18 * * ?";
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -272,9 +286,9 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static Boolean DEFAULT_ENABLE = true;
+		public static final Boolean DEFAULT_ENABLE = true;
 
-		public final static String DEFAULT_CRON = "45 0/15 8-18 * * ?";
+		public static final String DEFAULT_CRON = "45 0/15 8-18 * * ?";
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -303,9 +317,9 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static Boolean DEFAULT_ENABLE = true;
+		public static final Boolean DEFAULT_ENABLE = true;
 
-		public final static String DEFAULT_CRON = "5 0/5 * * * ?";
+		public static final String DEFAULT_CRON = "5 0/5 * * * ?";
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -334,11 +348,11 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static Boolean DEFAULT_ENABLE = false;
+		public static final Boolean DEFAULT_ENABLE = false;
 
-		public final static String DEFAULT_CRON = "30 30 6 * * ?";
+		public static final String DEFAULT_CRON = "30 30 6 * * ?";
 
-		public final static Integer DEFAULT_THRESHOLDDAYS = 365 * 2;
+		public static final Integer DEFAULT_THRESHOLDDAYS = 365 * 2;
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -374,11 +388,11 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static String DEFAULT_CRON = "30 30 12 * * ?";
+		public static final String DEFAULT_CRON = "30 30 12 * * ?";
 
-		public final static Boolean DEFAULT_ENABLE = true;
+		public static final Boolean DEFAULT_ENABLE = true;
 
-		public final static Integer DEFAULT_THRESHOLDMINUTES = 60 * 24;
+		public static final Integer DEFAULT_THRESHOLDMINUTES = 60 * 24;
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -414,11 +428,11 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static String DEFAULT_CRON = "0 0 20 * * ?";
+		public static final String DEFAULT_CRON = "0 0 20 * * ?";
 
-		public final static Boolean DEFAULT_ENABLE = false;
+		public static final Boolean DEFAULT_ENABLE = false;
 
-		public final static Integer DEFAULT_THRESHOLDMINUTES = 60 * 24 * 60;
+		public static final Integer DEFAULT_THRESHOLDMINUTES = 60 * 24 * 60;
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -454,9 +468,9 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static String DEFAULT_CRON = "5 5 8-18 * * ?";
+		public static final String DEFAULT_CRON = "5 5 8-18 * * ?";
 
-		public final static Boolean DEFAULT_ENABLE = true;
+		public static final Boolean DEFAULT_ENABLE = true;
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -484,15 +498,15 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static String DEFAULT_CRON = "0 0 4 * * ?";
+		public static final String DEFAULT_CRON = "0 0 4 * * ?";
 
-		public final static Boolean DEFAULT_ENABLE = true;
+		public static final Boolean DEFAULT_ENABLE = true;
 
-		public final static Integer DEFAULT_TASKTHRESHOLDMINUTES = 60 * 24 * 10;
+		public static final Integer DEFAULT_TASKTHRESHOLDMINUTES = 60 * 24 * 10;
 
-		public final static Integer DEFAULT_READTHRESHOLDMINUTES = 60 * 24 * 10;
+		public static final Integer DEFAULT_READTHRESHOLDMINUTES = 60 * 24 * 10;
 
-		public final static Integer DEFAULT_WORKTHRESHOLDMINUTES = 60 * 24 * 10;
+		public static final Integer DEFAULT_WORKTHRESHOLDMINUTES = 60 * 24 * 10;
 
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
@@ -545,9 +559,9 @@ public class ProcessPlatform extends ConfigObject {
 			return o;
 		}
 
-		public final static Integer DEFAULT_INTERVALMINUTES = 10;
+		public static final Integer DEFAULT_INTERVALMINUTES = 10;
 
-		public final static Integer DEFAULT_COUNT = 3;
+		public static final Integer DEFAULT_COUNT = 3;
 
 		@FieldDescribe("提醒间隔(分钟)")
 		private Integer intervalMinutes = DEFAULT_INTERVALMINUTES;
@@ -575,10 +589,6 @@ public class ProcessPlatform extends ConfigObject {
 
 	public static class ExtensionEvents {
 
-		// public static ExtensionEvents defaultInstance() {
-		// return new ExtensionEvents();
-		// }
-
 		@FieldDescribe("工作附件上传.")
 		private WorkExtensionEvents workAttachmentUploadEvents = new WorkExtensionEvents();
 		@FieldDescribe("工作附件下载.")
@@ -807,20 +817,4 @@ public class ProcessPlatform extends ConfigObject {
 
 	}
 
-	public static class ProcessingSignal extends ConfigObject {
-
-		public static final Integer DEFAULT_SPLITTHRESHOLD = 5;
-
-		private Integer splitThreshold = DEFAULT_SPLITTHRESHOLD;
-
-		public Integer getSplitThreshold() {
-			return splitThreshold == null ? DEFAULT_SPLITTHRESHOLD : this.splitThreshold;
-		}
-
-		public void setSplitThreshold(Integer splitThreshold) {
-			this.splitThreshold = splitThreshold;
-		}
-
-	}
-
 }

+ 0 - 56
o2server/x_base_core_project/src/main/java/com/x/base/core/project/executor/Signal.java

@@ -1,56 +0,0 @@
-package com.x.base.core.project.executor;
-
-import java.io.Closeable;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-
-import org.apache.commons.io.IOUtils;
-
-public class Signal implements Closeable {
-
-	private PipedInputStream input;
-	private PipedOutputStream output;
-	private volatile boolean completed = false;
-
-	public Signal() {
-		try {
-			this.output = new PipedOutputStream();
-			this.input = new PipedInputStream();
-			input.connect(output);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void write(String text) {
-		try {
-			if (!completed) {
-				this.output.write(Objects.toString(text, "").getBytes(StandardCharsets.UTF_8));
-				this.output.close();
-				completed = true;
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	public String read() {
-		String value = null;
-		try {
-			value = IOUtils.toString(this.input, StandardCharsets.UTF_8);
-			input.close();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		return value;
-	}
-
-	@Override
-	public void close() {
-		IOUtils.closeQuietly(output, null);
-		IOUtils.closeQuietly(input, null);
-	}
-
-}

+ 1 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_processplatform_service_processing.java

@@ -27,7 +27,7 @@ import com.x.base.core.project.annotation.ModuleType;
 		"com.x.processplatform.core.entity.element.Delay", "com.x.processplatform.core.entity.element.File",
 		"com.x.processplatform.core.entity.element.Form", "com.x.processplatform.core.entity.element.FormField",
 		"com.x.processplatform.core.entity.element.Embed", "com.x.processplatform.core.entity.element.Mapping",
-		"com.x.processplatform.core.entity.log.ProcessingError", "com.x.query.core.entity.Item",
+		"com.x.processplatform.core.entity.log.SignalStackLog", "com.x.query.core.entity.Item",
 		"com.x.query.dynamic.entity.*" }, storageTypes = { StorageType.processPlatform }, storeJars = {
 				"x_organization_core_entity", "x_organization_core_express", "x_processplatform_core_entity",
 				"x_processplatform_core_express", "x_query_core_entity" }, dynamicJars = { "x_query_dynamic_entity" })

+ 2 - 0
o2server/x_console/src/main/java/com/x/server/console/action/EraseContentLog.java

@@ -3,6 +3,7 @@ package com.x.server.console.action;
 import com.x.processplatform.core.entity.element.FormVersion;
 import com.x.processplatform.core.entity.element.ProcessVersion;
 import com.x.processplatform.core.entity.element.ScriptVersion;
+import com.x.processplatform.core.entity.log.SignalStackLog;
 import com.x.program.center.core.entity.PromptErrorLog;
 import com.x.program.center.core.entity.ScheduleLog;
 import com.x.program.center.core.entity.UnexpectedErrorLog;
@@ -20,6 +21,7 @@ public class EraseContentLog extends EraseContent {
 		addClass(ProcessVersion.class);
 		addClass(FormVersion.class);
 		addClass(ScriptVersion.class);
+		addClass(SignalStackLog.class);
 		this.run();
 		return true;
 	}

+ 2 - 0
o2server/x_console/src/main/java/com/x/server/console/action/EraseContentProcessPlatform.java

@@ -14,6 +14,7 @@ import com.x.processplatform.core.entity.content.TaskCompleted;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.content.WorkCompleted;
 import com.x.processplatform.core.entity.content.WorkLog;
+import com.x.processplatform.core.entity.log.SignalStackLog;
 import com.x.query.core.entity.Item;
 
 public class EraseContentProcessPlatform extends EraseContent {
@@ -34,6 +35,7 @@ public class EraseContentProcessPlatform extends EraseContent {
 		addClass(WorkCompleted.class);
 		addClass(WorkLog.class);
 		addClass(Item.class);
+		addClass(SignalStackLog.class);
 		this.run();
 		return true;
 	}

+ 149 - 152
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/ActionProcessing.java

@@ -3,6 +3,7 @@ package com.x.processplatform.assemble.surface.jaxrs.task;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.BooleanUtils;
@@ -20,7 +21,6 @@ import com.x.base.core.project.bean.WrapCopierFactory;
 import com.x.base.core.project.config.Config;
 import com.x.base.core.project.exception.ExceptionAccessDenied;
 import com.x.base.core.project.exception.ExceptionEntityNotExist;
-import com.x.base.core.project.executor.Signal;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -43,8 +43,9 @@ import com.x.processplatform.core.entity.content.WorkCompleted;
 import com.x.processplatform.core.entity.content.WorkLog;
 import com.x.processplatform.core.entity.element.Manual;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.SignalStack;
 import com.x.processplatform.core.express.ProcessingAttributes;
-import com.x.processplatform.core.express.ProcessingSignal;
+import com.x.processplatform.core.express.service.processing.jaxrs.task.ActionProcessingWo;
 import com.x.processplatform.core.express.service.processing.jaxrs.task.WrapAppend;
 import com.x.processplatform.core.express.service.processing.jaxrs.task.WrapProcessing;
 import com.x.processplatform.core.express.service.processing.jaxrs.task.WrapUpdatePrevTaskIdentity;
@@ -62,12 +63,12 @@ class ActionProcessing extends BaseAction {
 	private WorkLog workLog;
 	private Work work;
 	private String taskCompletedId;
-	private String type;
+	private String type = TYPE_TASK;
+	private Boolean asyncSupported = true;
 	private EffectivePerson effectivePerson;
 	private List<TaskCompleted> taskCompleteds = new ArrayList<>();
 	private List<Task> newTasks = new ArrayList<>();
 	private Exception exception = null;
-	private Signal signal = new Signal();
 
 	private Record record;
 	private String series = StringTools.uniqueToken();
@@ -76,108 +77,150 @@ class ActionProcessing extends BaseAction {
 	private static final String TYPE_TASK = "task";
 
 	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id, JsonElement jsonElement) throws Exception {
+
 		Audit audit = logger.audit(effectivePerson);
-		this.effectivePerson = effectivePerson;
-		wi = this.convertToWrapIn(jsonElement, Wi.class);
+
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			Business business = new Business(emc);
-			this.task = emc.find(id, Task.class);
-			if (null == this.task) {
-				throw new ExceptionEntityNotExist(id, Task.class);
-			}
-			// 获取当前环节已经完成的待办
-			this.taskCompleteds = emc.listEqual(TaskCompleted.class, TaskCompleted.activityToken_FIELDNAME,
-					task.getActivityToken());
-			this.workLog = emc.firstEqualAndEqual(WorkLog.class, WorkLog.job_FIELDNAME, task.getJob(),
-					WorkLog.fromActivityToken_FIELDNAME, task.getActivityToken());
-
-			if (null == workLog) {
-				throw new ExceptionEntityNotExist(WorkLog.class);
-			}
-			this.work = emc.find(this.task.getWork(), Work.class);
-			if (null == this.work) {
-				throw new ExceptionEntityNotExist(this.task.getWork(), Work.class);
-			}
-			if ((!effectivePerson.isCipher()) && effectivePerson.isNotPerson(this.task.getPerson())) {
-				throw new ExceptionAccessDenied(effectivePerson, this.task);
-			}
-			if (StringUtils.isNotEmpty(wi.getRouteName()) || StringUtils.isNotEmpty(wi.getOpinion())
-					|| (!StringUtils.equals(this.task.getMediaOpinion(), wi.getMediaOpinion()))) {
-				emc.beginTransaction(Task.class);
-				this.updateRouteNameOpinionMediaOpinion(task, wi);
-				emc.commit();
-			}
-			this.type = this.type(business, task, wi);
+			init(effectivePerson, business, id, jsonElement);
+			updateTaskIfNecessary(business);
+			seeManual(business);
 		}
+
+		LinkedBlockingQueue<Wo> responeQueue = new LinkedBlockingQueue<>();
+
 		new Thread(() -> {
-			if (StringUtils.equals(type, TYPE_APPENDTASK)) {
-				exception = processingAppendTask();
-			} else {
-				exception = processingTask();
+			Wo wo = new Wo();
+			try {
+				if (StringUtils.equals(type, TYPE_APPENDTASK)) {
+					processingAppendTask();
+				} else {
+					processingTask();
+				}
+				wo = Wo.copier.copy(record);
+			} catch (Exception e) {
+				exception = e;
+			} finally {
+				try {
+					responeQueue.put(wo);
+				} catch (Exception e) {
+					exception = e;
+				}
 			}
-			signal.close();
-		}, String.format("%s:%s", ActionProcessing.class.getName(), id)).start();
+		}, String.format("%s:processing:%s", ActionProcessing.class.getName(), id)).start();
+
+		if (BooleanUtils.isNotFalse(this.asyncSupported)) {
+			new Thread(() -> {
+				RespProcessingSignal resp = null;
+				try {
+					resp = ThisApplication
+							.context().applications().getQuery(effectivePerson.getDebugger(),
+									x_processplatform_service_processing.class, Applications.joinQueryUri("work",
+											task.getWork(), "series", series, "processing", "signal"),
+									task.getJob())
+							.getData(RespProcessingSignal.class);
+				} catch (Exception e) {
+					exception = e;
+				} finally {
+					Wo wo = new Wo();
+					if ((null != resp) && (null != resp.getSignalStack()) && (!resp.getSignalStack().isEmpty())) {
+						wo.setOccurSignalStack(true);
+						wo.setSignalStack(resp.getSignalStack());
+					} else {
+						wo.setOccurSignalStack(false);
+					}
+					try {
+						responeQueue.put(wo);
+					} catch (Exception e) {
+						exception = e;
+					}
+				}
+			}, String.format("%s:processingSignal:%s", ActionProcessing.class.getName(), id)).start();
+		}
+
+		Wo wo = responeQueue.take();
+
 		if (exception != null) {
 			throw exception;
 		}
-		String value = signal.read();
-		if (StringUtils.isNotBlank(value)) {
-			Wo wo = gson.fromJson(value, Wo.class);
-			result.setData(wo);
-			return result;
-		}
 		audit.log(null, "任务处理");
-		Wo wo = Wo.copier.copy(record);
 		result.setData(wo);
 		return result;
 	}
 
-	private void updateRouteNameOpinionMediaOpinion(Task task, Wi wi) {
-		/* 如果有输入新的路由决策覆盖原有决策 */
-		if (StringUtils.isNotEmpty(wi.getRouteName())) {
-			task.setRouteName(wi.getRouteName());
+	private void init(EffectivePerson effectivePerson, Business business, String id, JsonElement jsonElement)
+			throws Exception {
+		EntityManagerContainer emc = business.entityManagerContainer();
+		this.effectivePerson = effectivePerson;
+		this.wi = this.convertToWrapIn(jsonElement, Wi.class);
+		this.task = emc.find(id, Task.class);
+		if (null == this.task) {
+			throw new ExceptionEntityNotExist(id, Task.class);
+		}
+		// 获取当前环节已经完成的待办
+		this.taskCompleteds = emc.listEqual(TaskCompleted.class, TaskCompleted.activityToken_FIELDNAME,
+				task.getActivityToken());
+		this.workLog = emc.firstEqualAndEqual(WorkLog.class, WorkLog.job_FIELDNAME, task.getJob(),
+				WorkLog.fromActivityToken_FIELDNAME, task.getActivityToken());
+
+		if (null == workLog) {
+			throw new ExceptionEntityNotExist(WorkLog.class);
+		}
+		this.work = emc.find(this.task.getWork(), Work.class);
+		if (null == this.work) {
+			throw new ExceptionEntityNotExist(this.task.getWork(), Work.class);
 		}
-		/* 如果有新的流程意见那么覆盖原有流程意见 */
-		if (StringUtils.isNotEmpty(wi.getOpinion())) {
-			task.setOpinion(wi.getOpinion());
+		if ((!effectivePerson.isCipher()) && effectivePerson.isNotPerson(this.task.getPerson())) {
+			throw new ExceptionAccessDenied(effectivePerson, this.task);
 		}
-		/* 强制覆盖多媒体意见 */
-		task.setMediaOpinion(wi.getMediaOpinion());
 	}
 
-	private String type(Business business, Task task, Wi wi) throws Exception {
-		Manual manual = business.manual().pick(task.getActivity());
+	private void updateTaskIfNecessary(Business business) throws Exception {
+		if (StringUtils.isNotEmpty(this.wi.getRouteName()) || StringUtils.isNotEmpty(this.wi.getOpinion())
+				|| (!StringUtils.equals(this.task.getMediaOpinion(), this.wi.getMediaOpinion()))) {
+			business.entityManagerContainer().beginTransaction(Task.class);
+			// 如果有输入新的路由决策覆盖原有决策
+			if (StringUtils.isNotEmpty(this.wi.getRouteName())) {
+				this.task.setRouteName(this.wi.getRouteName());
+			}
+			// 如果有新的流程意见那么覆盖原有流程意见
+			if (StringUtils.isNotEmpty(this.wi.getOpinion())) {
+				this.task.setOpinion(this.wi.getOpinion());
+			}
+			// 强制覆盖多媒体意见
+			this.task.setMediaOpinion(this.wi.getMediaOpinion());
+			business.entityManagerContainer().commit();
+		}
+	}
+
+	private void seeManual(Business business) throws Exception {
+		Manual manual = business.manual().pick(this.task.getActivity());
 		if (null != manual) {
+			this.asyncSupported = BooleanUtils.isNotFalse(manual.getAsyncSupported());
 			Route route = null;
 			for (Route o : business.route().pick(manual.getRouteList())) {
-				if (StringUtils.equals(o.getName(), task.getRouteName())) {
+				if (StringUtils.equals(o.getName(), this.task.getRouteName())) {
 					route = o;
 					break;
 				}
 			}
 			if ((null != route) && (StringUtils.equals(route.getType(), Route.TYPE_APPENDTASK))
 					&& StringUtils.equals(manual.getId(), route.getActivity())) {
-				return TYPE_APPENDTASK;
+				this.type = TYPE_APPENDTASK;
 			}
 		}
-		return TYPE_TASK;
 	}
 
-	private Exception processingAppendTask() {
-		try {
-			this.processingAppendTask_append();
-			this.taskCompletedId = this.processing_processingTask(TaskCompleted.PROCESSINGTYPE_APPENDTASK);
-			this.processing_processingWork(ProcessingAttributes.TYPE_APPENDTASK);
-			this.processing_record(Record.TYPE_APPENDTASK);
-			this.processing_updateTaskCompleted();
-			this.processing_updateTask();
-			return null;
-		} catch (Exception e) {
-			return e;
-		}
+	private void processingAppendTask() throws Exception {
+		this.processingAppendTaskAppend();
+		this.taskCompletedId = this.processingProcessingTask(TaskCompleted.PROCESSINGTYPE_APPENDTASK);
+		this.processingProcessingWork(ProcessingAttributes.TYPE_APPENDTASK);
+		this.processingRecord(Record.TYPE_APPENDTASK);
+		this.processingUpdateTaskCompleted();
+		this.processingUpdateTask();
 	}
 
-	private void processingAppendTask_append() throws Exception {
+	private void processingAppendTaskAppend() throws Exception {
 		WrapAppend req = new WrapAppend();
 		req.setIdentityList(this.wi.getAppendTaskIdentityList());
 		ThisApplication.context().applications()
@@ -186,34 +229,29 @@ class ActionProcessing extends BaseAction {
 				.getData(WrapStringList.class);
 	}
 
-	private Exception processingTask() {
-		try {
-			this.taskCompletedId = this.processing_processingTask(TaskCompleted.PROCESSINGTYPE_TASK);
-			this.processing_processingWork(ProcessingAttributes.TYPE_TASK);
-			// 流程流转到取消环节,此时工作已被删除
-			boolean flag = true;
-			try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-				if ((emc.countEqual(Work.class, Work.job_FIELDNAME, task.getJob()) == 0)
-						&& (emc.countEqual(WorkCompleted.class, WorkCompleted.job_FIELDNAME, task.getJob()) == 0)) {
-					flag = false;
-				}
-			}
-			if (flag) {
-				this.processing_record(Record.TYPE_TASK);
-				this.processing_updateTaskCompleted();
-				this.processing_updateTask();
-			} else {
-				record = new Record(workLog, task);
-				record.setCompleted(true);
-				record.setType(Record.TYPE_TASK);
+	private void processingTask() throws Exception {
+		this.taskCompletedId = this.processingProcessingTask(TaskCompleted.PROCESSINGTYPE_TASK);
+		this.processingProcessingWork(ProcessingAttributes.TYPE_TASK);
+		// 流程流转到取消环节,此时工作已被删除
+		boolean flag = true;
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			if ((emc.countEqual(Work.class, Work.job_FIELDNAME, task.getJob()) == 0)
+					&& (emc.countEqual(WorkCompleted.class, WorkCompleted.job_FIELDNAME, task.getJob()) == 0)) {
+				flag = false;
 			}
-			return null;
-		} catch (Exception e) {
-			return e;
+		}
+		if (flag) {
+			this.processingRecord(Record.TYPE_TASK);
+			this.processingUpdateTaskCompleted();
+			this.processingUpdateTask();
+		} else {
+			record = new Record(workLog, task);
+			record.setCompleted(true);
+			record.setType(Record.TYPE_TASK);
 		}
 	}
 
-	private String processing_processingTask(String processType) throws Exception {
+	private String processingProcessingTask(String processType) throws Exception {
 		WrapProcessing req = new WrapProcessing();
 		req.setProcessingType(processType);
 		WoId resp = ThisApplication.context().applications()
@@ -228,26 +266,23 @@ class ActionProcessing extends BaseAction {
 		}
 	}
 
-	private void processing_processingWork(String type) throws Exception {
+	private void processingProcessingWork(String workProcessingType) throws Exception {
 		ProcessingAttributes req = new ProcessingAttributes();
 		req.setIgnoreEmpowerIdentityList(wi.getIgnoreEmpowerIdentityList());
-		req.setType(ProcessingAttributes.TYPE_TASK);
+		req.setType(workProcessingType);
 		req.setSeries(this.series);
 		req.setPerson(task.getPerson());
 		req.setIdentity(task.getIdentity());
-		RespOfProcessWork resp = ThisApplication.context().applications()
+		WoId resp = ThisApplication.context().applications()
 				.putQuery(effectivePerson.getDebugger(), x_processplatform_service_processing.class,
 						Applications.joinQueryUri("work", task.getWork(), "processing"), req, task.getJob())
-				.getData(RespOfProcessWork.class);
-		if (BooleanUtils.isTrue(resp.getOccurProcessingSignal())) {
-			signal.write(gson.toJson(resp));
-		}
+				.getData(WoId.class);
 		if (StringUtils.isBlank(resp.getId())) {
 			throw new ExceptionWorkProcessing(task.getId());
 		}
 	}
 
-	private void processing_record(String type) throws Exception {
+	private void processingRecord(String type) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			final List<String> nextTaskIdentities = new ArrayList<>();
 			record = new Record(workLog, task);
@@ -301,7 +336,7 @@ class ActionProcessing extends BaseAction {
 		}
 	}
 
-	private void processing_updateTaskCompleted() throws Exception {
+	private void processingUpdateTaskCompleted() throws Exception {
 		// 记录下一处理人信息
 		WrapUpdateNextTaskIdentity req = new WrapUpdateNextTaskIdentity();
 		req.getTaskCompletedList().add(taskCompletedId);
@@ -312,7 +347,7 @@ class ActionProcessing extends BaseAction {
 				.getData(WrapBoolean.class);
 	}
 
-	private void processing_updateTask() throws Exception {
+	private void processingUpdateTask() throws Exception {
 		// 记录上一处理人信息
 		if (ListTools.isNotEmpty(newTasks)) {
 			WrapUpdatePrevTaskIdentity req = new WrapUpdatePrevTaskIdentity();
@@ -413,32 +448,12 @@ class ActionProcessing extends BaseAction {
 		return o;
 	}
 
-	public static class Wo extends Record {
+	public static class Wo extends ActionProcessingWo {
 
 		private static final long serialVersionUID = -1771383649634969945L;
 		static WrapCopier<Record, Wo> copier = WrapCopierFactory.wo(Record.class, Wo.class, null,
 				JpaObject.FieldsInvisible);
 
-		private ProcessingSignal processingSignal;
-
-		private Boolean occurProcessingSignal;
-
-		public ProcessingSignal getProcessingSignal() {
-			return processingSignal;
-		}
-
-		public void setProcessingSignal(ProcessingSignal processingSignal) {
-			this.processingSignal = processingSignal;
-		}
-
-		public Boolean getOccurProcessingSignal() {
-			return occurProcessingSignal;
-		}
-
-		public void setOccurProcessingSignal(Boolean occurProcessingSignal) {
-			this.occurProcessingSignal = occurProcessingSignal;
-		}
-
 	}
 
 	public static class WoTask extends Task {
@@ -452,34 +467,16 @@ class ActionProcessing extends BaseAction {
 
 	}
 
-	public static class RespOfProcessWork {
-
-		private String id;
-		private Boolean occurProcessingSignal;
-		private ProcessingSignal processingSignal;
+	public static class RespProcessingSignal {
 
-		public Boolean getOccurProcessingSignal() {
-			return occurProcessingSignal;
-		}
-
-		public void setOccurProcessingSignal(Boolean occurProcessingSignal) {
-			this.occurProcessingSignal = occurProcessingSignal;
-		}
-
-		public ProcessingSignal getProcessingSignal() {
-			return processingSignal;
-		}
-
-		public void setProcessingSignal(ProcessingSignal processingSignal) {
-			this.processingSignal = processingSignal;
-		}
+		private SignalStack signalStack;
 
-		public String getId() {
-			return id;
+		public SignalStack getSignalStack() {
+			return signalStack;
 		}
 
-		public void setId(String id) {
-			this.id = id;
+		public void setSignalStack(SignalStack signalStack) {
+			this.signalStack = signalStack;
 		}
 
 	}

+ 9 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/ProcessingRunnableImpl.java

@@ -0,0 +1,9 @@
+package com.x.processplatform.assemble.surface.jaxrs.task;
+
+public class ProcessingRunnableImpl implements Runnable {
+
+	public void run() {
+		// TODO Auto-generated method stub
+
+	}
+}

+ 2 - 2
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/PersistenceProperties.java

@@ -203,8 +203,8 @@ public final class PersistenceProperties extends AbstractPersistenceProperties {
 	}
 
 	public static class Log {
-		public static class ProcessingError {
-			public static final String table = "PP_L_PROCESSINGERROR";
+		public static class SignalStackLog {
+			public static final String table = "PP_L_SIGNALSTACKLOG";
 		}
 	}
 

+ 0 - 8
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/content/Work.java

@@ -848,14 +848,6 @@ public class Work extends SliceJpaObject implements ProjectionInterface {
 		this.form = form;
 	}
 
-	// public Integer getErrorRetry() {
-	// return errorRetry;
-	// }
-	//
-	// public void setErrorRetry(Integer errorRetry) {
-	// this.errorRetry = errorRetry;
-	// }
-
 	public String getDestinationRoute() {
 		return destinationRoute;
 	}

+ 42 - 3
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/Manual.java

@@ -13,14 +13,18 @@ import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
 import javax.persistence.Lob;
 import javax.persistence.OrderColumn;
+import javax.persistence.PostLoad;
 import javax.persistence.Table;
+import javax.persistence.Transient;
 import javax.persistence.UniqueConstraint;
 
+import org.apache.openjpa.persistence.Persistent;
 import org.apache.openjpa.persistence.PersistentCollection;
 import org.apache.openjpa.persistence.jdbc.ContainerTable;
 import org.apache.openjpa.persistence.jdbc.ElementColumn;
 import org.apache.openjpa.persistence.jdbc.ElementIndex;
 import org.apache.openjpa.persistence.jdbc.Index;
+import org.apache.openjpa.persistence.jdbc.Strategy;
 
 import com.x.base.core.entity.AbstractPersistenceProperties;
 import com.x.base.core.entity.JpaObject;
@@ -62,10 +66,33 @@ public class Manual extends Activity {
 		// nothing
 	}
 
-	/* 更新运行方法 */
+	@PostLoad
+	public void postLoad() {
+		this.asyncSupported = this.getProperties().getAsyncSupported();
+	}
+
+	public Manual() {
+		this.properties = new ManualProperties();
+	}
 
-	/* flag标志位 */
-	/* Entity 默认字段结束 */
+	public ManualProperties getProperties() {
+		if (null == this.properties) {
+			this.properties = new ManualProperties();
+		}
+		return this.properties;
+	}
+
+	public Boolean getAsyncSupported() {
+		return asyncSupported;
+	}
+
+	public void setAsyncSupported(Boolean asyncSupported) {
+		this.asyncSupported = asyncSupported;
+		this.getProperties().setAsyncSupported(asyncSupported);
+	}
+
+	@Transient
+	private Boolean asyncSupported;
 
 	@FieldDescribe("分组")
 	@CheckPersist(allowEmpty = true)
@@ -601,6 +628,18 @@ public class Manual extends Activity {
 	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + edition_FIELDNAME)
 	private String edition;
 
+	public static final String properties_FIELDNAME = "properties";
+	@FieldDescribe("属性对象存储字段.")
+	@Persistent(fetch = FetchType.EAGER)
+	@Strategy(JsonPropertiesValueHandler)
+	@Column(length = JpaObject.length_10M, name = ColumnNamePrefix + properties_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private ManualProperties properties;
+
+	public void setProperties(ManualProperties properties) {
+		this.properties = properties;
+	}
+
 	public String getDisplayLogScript() {
 		return displayLogScript;
 	}

+ 19 - 0
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/ManualProperties.java

@@ -0,0 +1,19 @@
+package com.x.processplatform.core.entity.element;
+
+import com.x.base.core.entity.JsonProperties;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+public class ManualProperties extends JsonProperties {
+
+	@FieldDescribe("是否启用异步返回.")
+	private Boolean asyncSupported = true;
+
+	public Boolean getAsyncSupported() {
+		return asyncSupported;
+	}
+
+	public void setAsyncSupported(Boolean asyncSupported) {
+		this.asyncSupported = asyncSupported;
+	}
+
+}

+ 0 - 105
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/ProcessingError.java

@@ -1,105 +0,0 @@
-package com.x.processplatform.core.entity.log;
-
-import java.util.Date;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Lob;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-
-import org.apache.openjpa.persistence.jdbc.Index;
-
-import com.x.base.core.entity.JpaObject;
-import com.x.base.core.entity.SliceJpaObject;
-import com.x.base.core.entity.annotation.ContainerEntity;
-import com.x.base.core.project.annotation.FieldDescribe;
-import com.x.base.core.project.tools.StringTools;
-import com.x.processplatform.core.entity.PersistenceProperties;
-
-@Entity
-@ContainerEntity(dumpSize = 1000, type = ContainerEntity.Type.content, reference = ContainerEntity.Reference.strong)
-@Table(name = PersistenceProperties.Log.ProcessingError.table, uniqueConstraints = {
-		@UniqueConstraint(name = PersistenceProperties.Log.ProcessingError.table + JpaObject.IndexNameMiddle
-				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
-						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
-@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
-public class ProcessingError extends SliceJpaObject {
-
-	private static final long serialVersionUID = 6696198642414522481L;
-
-	private static final String TABLE = PersistenceProperties.Log.ProcessingError.table;
-
-	public String getId() {
-		return id;
-	}
-
-	public void setId(String id) {
-		this.id = id;
-	}
-
-	@FieldDescribe("数据库主键,自动生成.")
-	@Id
-	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
-	private String id = createId();
-
-	/* 以上为 JpaObject 默认字段 */
-
-	public void onPersist() throws Exception {
-	}
-
-	public void setMessage(String message) {
-		if (StringTools.utf8Length(message) > JpaObject.length_255B) {
-			this.message = StringTools.utf8SubString(message, length_255B);
-		} else {
-			this.message = message;
-		}
-	}
-
-	/* 更新运行方法 */
-
-	public static final String work_FIELDNAME = "work";
-	@FieldDescribe("工作")
-	@Column(length = JpaObject.length_id, name = ColumnNamePrefix + work_FIELDNAME)
-	@Index(name = TABLE + IndexNameMiddle + work_FIELDNAME)
-	private String work;
-
-	public static final String message_FIELDNAME = "message";
-	@FieldDescribe("错误消息")
-	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + message_FIELDNAME)
-	@Index(name = TABLE + IndexNameMiddle + message_FIELDNAME)
-	private String message;
-
-	public static final String data_FIELDNAME = "data";
-	@FieldDescribe("文本内容.")
-	@Lob
-	@Basic(fetch = FetchType.EAGER)
-	@Column(length = JpaObject.length_1M, name = ColumnNamePrefix + data_FIELDNAME)
-	private String data;
-
-	public String getWork() {
-		return work;
-	}
-
-	public void setWork(String work) {
-		this.work = work;
-	}
-
-	public String getMessage() {
-		return message;
-	}
-
-	public String getData() {
-		return data;
-	}
-
-	public void setData(String data) {
-		this.data = data;
-	}
-
-}

+ 841 - 0
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/Signal.java

@@ -0,0 +1,841 @@
+package com.x.processplatform.core.entity.log;
+
+import java.util.Date;
+import java.util.List;
+
+import com.x.base.core.project.gson.GsonPropertyObject;
+
+public class Signal extends GsonPropertyObject {
+
+	public static final String TYPE_AGENTARRIVE = "agentArrive";
+	public static final String TYPE_AGENTEXECUTE = "agentExecute";
+	public static final String TYPE_AGENTINQUIRE = "agentInquire";
+
+	private AgentArrive agentArrive;
+	private AgentExecute agentExecute;
+	private AgentInquire agentInquire;
+
+	public AgentArrive getAgentArrive() {
+		return agentArrive;
+	}
+
+	public AgentExecute getAgentExecute() {
+		return agentExecute;
+	}
+
+	public AgentInquire getAgentInquire() {
+		return agentInquire;
+	}
+
+	public static class AgentArrive extends Base {
+
+	}
+
+	public static Signal agentArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_AGENTARRIVE;
+		AgentArrive s = new AgentArrive();
+		p.agentArrive = s;
+		return p;
+	}
+
+	public static class AgentExecute extends Base {
+
+	}
+
+	public static Signal agentExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_AGENTEXECUTE;
+		AgentExecute s = new AgentExecute();
+		p.agentExecute = s;
+		return p;
+	}
+
+	public static class AgentInquire extends Base {
+
+	}
+
+	public static Signal agentInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_AGENTINQUIRE;
+		AgentInquire s = new AgentInquire();
+		p.agentInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_BEGINARRIVE = "beginArrive";
+	public static final String TYPE_BEGINEXECUTE = "beginExecute";
+	public static final String TYPE_BEGININQUIRE = "beginInquire";
+
+	private BeginArrive beginArrive;
+	private BeginExecute beginExecute;
+	private BeginInquire beginInquire;
+
+	public BeginArrive getBeginArrive() {
+		return beginArrive;
+	}
+
+	public BeginExecute getBeginExecute() {
+		return beginExecute;
+	}
+
+	public BeginInquire getBeginInquire() {
+		return beginInquire;
+	}
+
+	public static class BeginArrive extends Base {
+
+	}
+
+	public static Signal beginArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_BEGINARRIVE;
+		BeginArrive s = new BeginArrive();
+		p.beginArrive = s;
+		return p;
+	}
+
+	public static class BeginExecute extends Base {
+
+	}
+
+	public static Signal beginExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_BEGINEXECUTE;
+		BeginExecute s = new BeginExecute();
+		p.beginExecute = s;
+		return p;
+	}
+
+	public static class BeginInquire extends Base {
+
+	}
+
+	public static Signal beginInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_BEGININQUIRE;
+		BeginInquire s = new BeginInquire();
+		p.beginInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_CANCELARRIVE = "cancelArrive";
+	public static final String TYPE_CANCELEXECUTE = "cancelExecute";
+	public static final String TYPE_CANCELINQUIRE = "cancelInquire";
+
+	private CancelArrive cancelArrive;
+	private CancelExecute cancelExecute;
+	private CancelInquire cancelInquire;
+
+	public CancelArrive getCancelArrive() {
+		return cancelArrive;
+	}
+
+	public CancelExecute getCancelExecute() {
+		return cancelExecute;
+	}
+
+	public CancelInquire getCancelInquire() {
+		return cancelInquire;
+	}
+
+	public static class CancelArrive extends Base {
+
+	}
+
+	public static Signal cancelArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_CANCELARRIVE;
+		CancelArrive s = new CancelArrive();
+		p.cancelArrive = s;
+		return p;
+	}
+
+	public static class CancelExecute extends Base {
+
+	}
+
+	public static Signal cancelExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_CANCELEXECUTE;
+		CancelExecute s = new CancelExecute();
+		p.cancelExecute = s;
+		return p;
+	}
+
+	public static class CancelInquire extends Base {
+
+	}
+
+	public static Signal cancelInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_CANCELINQUIRE;
+		CancelInquire s = new CancelInquire();
+		p.cancelInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_CHOICEARRIVE = "choiceArrive";
+	public static final String TYPE_CHOICEEXECUTE = "choiceExecute";
+	public static final String TYPE_CHOICEINQUIRE = "choiceInquire";
+
+	private ChoiceArrive choiceArrive;
+	private ChoiceExecute choiceExecute;
+	private ChoiceInquire choiceInquire;
+
+	public ChoiceArrive getChoiceArrive() {
+		return choiceArrive;
+	}
+
+	public ChoiceExecute getChoiceExecute() {
+		return choiceExecute;
+	}
+
+	public ChoiceInquire getChoiceInquire() {
+		return choiceInquire;
+	}
+
+	public static class ChoiceArrive extends Base {
+
+	}
+
+	public static Signal choiceArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_CHOICEARRIVE;
+		ChoiceArrive s = new ChoiceArrive();
+		p.choiceArrive = s;
+		return p;
+	}
+
+	public static class ChoiceExecute extends Base {
+
+	}
+
+	public static Signal choiceExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_CHOICEEXECUTE;
+		ChoiceExecute s = new ChoiceExecute();
+		p.choiceExecute = s;
+		return p;
+	}
+
+	public static class ChoiceInquire extends Base {
+
+	}
+
+	public static Signal choiceInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_CHOICEINQUIRE;
+		ChoiceInquire s = new ChoiceInquire();
+		p.choiceInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_DELAYARRIVE = "delayArrive";
+	public static final String TYPE_DELAYEXECUTE = "delayExecute";
+	public static final String TYPE_DELAYINQUIRE = "delayInquire";
+
+	private DelayArrive delayArrive;
+	private DelayExecute delayExecute;
+	private DelayInquire delayInquire;
+
+	public DelayArrive getDelayArrive() {
+		return delayArrive;
+	}
+
+	public DelayExecute getDelayExecute() {
+		return delayExecute;
+	}
+
+	public DelayInquire getDelayInquire() {
+		return delayInquire;
+	}
+
+	public static class DelayArrive extends Base {
+
+	}
+
+	public static Signal delayArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_DELAYARRIVE;
+		DelayArrive s = new DelayArrive();
+		p.delayArrive = s;
+		return p;
+	}
+
+	public static class DelayExecute extends Base {
+
+	}
+
+	public static Signal delayExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_DELAYEXECUTE;
+		DelayExecute s = new DelayExecute();
+		p.delayExecute = s;
+		return p;
+	}
+
+	public static class DelayInquire extends Base {
+
+	}
+
+	public static Signal delayInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_DELAYINQUIRE;
+		DelayInquire s = new DelayInquire();
+		p.delayInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_EMBEDARRIVE = "embedArrive";
+	public static final String TYPE_EMBEDEXECUTE = "embedExecute";
+	public static final String TYPE_EMBEDINQUIRE = "embedInquire";
+
+	private EmbedArrive embedArrive;
+	private EmbedExecute embedExecute;
+	private EmbedInquire embedInquire;
+
+	public EmbedArrive getEmbedArrive() {
+		return embedArrive;
+	}
+
+	public EmbedExecute getEmbedExecute() {
+		return embedExecute;
+	}
+
+	public EmbedInquire getEmbedInquire() {
+		return embedInquire;
+	}
+
+	public static class EmbedArrive extends Base {
+
+	}
+
+	public static Signal embedArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_EMBEDARRIVE;
+		EmbedArrive s = new EmbedArrive();
+		p.embedArrive = s;
+		return p;
+	}
+
+	public static class EmbedExecute extends Base {
+
+	}
+
+	public static Signal embedExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_EMBEDEXECUTE;
+		EmbedExecute s = new EmbedExecute();
+		p.embedExecute = s;
+		return p;
+	}
+
+	public static class EmbedInquire extends Base {
+
+	}
+
+	public static Signal embedInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_EMBEDINQUIRE;
+		EmbedInquire s = new EmbedInquire();
+		p.embedInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_ENDARRIVE = "endArrive";
+	public static final String TYPE_ENDEXECUTE = "endExecute";
+	public static final String TYPE_ENDINQUIRE = "endInquire";
+
+	private EndArrive endArrive;
+	private EndExecute endExecute;
+	private EndInquire endInquire;
+
+	public EndArrive getEndArrive() {
+		return endArrive;
+	}
+
+	public EndExecute getEndExecute() {
+		return endExecute;
+	}
+
+	public EndInquire getEndInquire() {
+		return endInquire;
+	}
+
+	public static class EndArrive extends Base {
+
+	}
+
+	public static Signal endArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_ENDARRIVE;
+		EndArrive s = new EndArrive();
+		p.endArrive = s;
+		return p;
+	}
+
+	public static class EndExecute extends Base {
+
+	}
+
+	public static Signal endExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_ENDEXECUTE;
+		EndExecute s = new EndExecute();
+		p.endExecute = s;
+		return p;
+	}
+
+	public static class EndInquire extends Base {
+
+	}
+
+	public static Signal endInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_ENDINQUIRE;
+		EndInquire s = new EndInquire();
+		p.endInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_INVOKEARRIVE = "invokeArrive";
+	public static final String TYPE_INVOKEEXECUTE = "invokeExecute";
+	public static final String TYPE_INVOKEINQUIRE = "invokeInquire";
+
+	private InvokeArrive invokeArrive;
+	private InvokeExecute invokeExecute;
+	private InvokeInquire invokeInquire;
+
+	public InvokeArrive getInvokeArrive() {
+		return invokeArrive;
+	}
+
+	public InvokeExecute getInvokeExecute() {
+		return invokeExecute;
+	}
+
+	public InvokeInquire getInvokeInquire() {
+		return invokeInquire;
+	}
+
+	public static class InvokeArrive extends Base {
+
+	}
+
+	public static Signal invokeArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_INVOKEARRIVE;
+		InvokeArrive s = new InvokeArrive();
+		p.invokeArrive = s;
+		return p;
+	}
+
+	public static class InvokeExecute extends Base {
+
+	}
+
+	public static Signal invokeExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_INVOKEEXECUTE;
+		InvokeExecute s = new InvokeExecute();
+		p.invokeExecute = s;
+		return p;
+	}
+
+	public static class InvokeInquire extends Base {
+
+	}
+
+	public static Signal invokeInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_INVOKEINQUIRE;
+		InvokeInquire s = new InvokeInquire();
+		p.invokeInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_MANUALARRIVE = "manualArrive";
+	public static final String TYPE_MANUALEXECUTE = "manualExecute";
+	public static final String TYPE_MANUALINQUIRE = "manualInquire";
+
+	private ManualArrive manualArrive;
+	private ManualExecute manualExecute;
+	private ManualInquire manualInquire;
+
+	public ManualArrive getManualArrive() {
+		return manualArrive;
+	}
+
+	public ManualExecute getManualExecute() {
+		return manualExecute;
+	}
+
+	public ManualInquire getManualInquire() {
+		return manualInquire;
+	}
+
+	public static class ManualArrive extends Base {
+
+	}
+
+	public static Signal manualArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_MANUALARRIVE;
+		ManualArrive s = new ManualArrive();
+		p.manualArrive = s;
+		return p;
+	}
+
+	public static class ManualExecute extends Base {
+
+		private String type;
+		private List<String> identities;
+
+		public String getType() {
+			return type;
+		}
+
+		public List<String> getIdentities() {
+			return identities;
+		}
+
+	}
+
+	public static Signal manualExecute(String type, List<String> identities) {
+		Signal p = new Signal();
+		p.type = TYPE_MANUALEXECUTE;
+		ManualExecute s = new ManualExecute();
+		s.type = type;
+		s.identities = identities;
+		p.manualExecute = s;
+		return p;
+	}
+
+	public static class ManualInquire extends Base {
+
+	}
+
+	public static Signal manualInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_MANUALINQUIRE;
+		ManualInquire s = new ManualInquire();
+		p.manualInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_MERGEARRIVE = "mergeArrive";
+	public static final String TYPE_MERGEEXECUTE = "mergeExecute";
+	public static final String TYPE_MERGEINQUIRE = "mergeInquire";
+
+	private MergeArrive mergeArrive;
+	private MergeExecute mergeExecute;
+	private MergeInquire mergeInquire;
+
+	public MergeArrive getMergeArrive() {
+		return mergeArrive;
+	}
+
+	public MergeExecute getMergeExecute() {
+		return mergeExecute;
+	}
+
+	public MergeInquire getMergeInquire() {
+		return mergeInquire;
+	}
+
+	public static class MergeArrive extends Base {
+
+	}
+
+	public static Signal mergeArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_MERGEARRIVE;
+		MergeArrive s = new MergeArrive();
+		p.mergeArrive = s;
+		return p;
+	}
+
+	public static class MergeExecute extends Base {
+
+	}
+
+	public static Signal mergeExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_MERGEEXECUTE;
+		MergeExecute s = new MergeExecute();
+		p.mergeExecute = s;
+		return p;
+	}
+
+	public static class MergeInquire extends Base {
+
+	}
+
+	public static Signal mergeInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_MERGEINQUIRE;
+		MergeInquire s = new MergeInquire();
+		p.mergeInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_MESSAGEARRIVE = "messageArrive";
+	public static final String TYPE_MESSAGEEXECUTE = "messageExecute";
+	public static final String TYPE_MESSAGEINQUIRE = "messageInquire";
+
+	private MessageArrive messageArrive;
+	private MessageExecute messageExecute;
+	private MessageInquire messageInquire;
+
+	public MessageArrive getMessageArrive() {
+		return messageArrive;
+	}
+
+	public MessageExecute getMessageExecute() {
+		return messageExecute;
+	}
+
+	public MessageInquire getMessageInquire() {
+		return messageInquire;
+	}
+
+	public static class MessageArrive extends Base {
+
+	}
+
+	public static Signal messageArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_MERGEARRIVE;
+		MessageArrive s = new MessageArrive();
+		p.messageArrive = s;
+		return p;
+	}
+
+	public static class MessageExecute extends Base {
+
+	}
+
+	public static Signal messageExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_MESSAGEEXECUTE;
+		MessageExecute s = new MessageExecute();
+		p.messageExecute = s;
+		return p;
+	}
+
+	public static class MessageInquire extends Base {
+
+	}
+
+	public static Signal messageInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_MESSAGEINQUIRE;
+		MessageInquire s = new MessageInquire();
+		p.messageInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_PARALLELARRIVE = "parallelArrive";
+	public static final String TYPE_PARALLELEXECUTE = "parallelExecute";
+	public static final String TYPE_PARALLELINQUIRE = "parallelInquire";
+
+	private ParallelArrive parallelArrive;
+	private ParallelExecute parallelExecute;
+	private ParallelInquire parallelInquire;
+
+	public ParallelArrive getParallelArrive() {
+		return parallelArrive;
+	}
+
+	public ParallelExecute getParallelExecute() {
+		return parallelExecute;
+	}
+
+	public ParallelInquire getParallelInquire() {
+		return parallelInquire;
+	}
+
+	public static class ParallelArrive extends Base {
+
+	}
+
+	public static Signal parallelArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_PARALLELARRIVE;
+		ParallelArrive s = new ParallelArrive();
+		p.parallelArrive = s;
+		return p;
+	}
+
+	public static class ParallelExecute extends Base {
+
+	}
+
+	public static Signal parallelExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_PARALLELEXECUTE;
+		ParallelExecute s = new ParallelExecute();
+		p.parallelExecute = s;
+		return p;
+	}
+
+	public static class ParallelInquire extends Base {
+
+	}
+
+	public static Signal parallelInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_PARALLELINQUIRE;
+		ParallelInquire s = new ParallelInquire();
+		p.parallelInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_SERVICEARRIVE = "serviceArrive";
+	public static final String TYPE_SERVICEEXECUTE = "serviceExecute";
+	public static final String TYPE_SERVICEINQUIRE = "serviceInquire";
+
+	private ServiceArrive serviceArrive;
+	private ServiceExecute serviceExecute;
+	private ServiceInquire serviceInquire;
+
+	public ServiceArrive getServiceArrive() {
+		return serviceArrive;
+	}
+
+	public ServiceExecute getServiceExecute() {
+		return serviceExecute;
+	}
+
+	public ServiceInquire getServiceInquire() {
+		return serviceInquire;
+	}
+
+	public static class ServiceArrive extends Base {
+
+	}
+
+	public static Signal serviceArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_SERVICEARRIVE;
+		ServiceArrive s = new ServiceArrive();
+		p.serviceArrive = s;
+		return p;
+	}
+
+	public static class ServiceExecute extends Base {
+
+	}
+
+	public static Signal serviceExecute() {
+		Signal p = new Signal();
+		p.type = TYPE_SERVICEEXECUTE;
+		ServiceExecute s = new ServiceExecute();
+		p.serviceExecute = s;
+		return p;
+	}
+
+	public static class ServiceInquire extends Base {
+
+	}
+
+	public static Signal serviceInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_SERVICEINQUIRE;
+		ServiceInquire s = new ServiceInquire();
+		p.serviceInquire = s;
+		return p;
+	}
+
+	public static final String TYPE_SPLITARRIVE = "splitArrive";
+	public static final String TYPE_SPLITEXECUTE = "splitExecute";
+	public static final String TYPE_SPLITINQUIRE = "splitInquire";
+
+	private SplitArrive splitArrive;
+	private SplitExecute splitExecute;
+	private SplitInquire splitInquire;
+
+	public SplitArrive getSplitArrive() {
+		return splitArrive;
+	}
+
+	public SplitExecute getSplitExecute() {
+		return splitExecute;
+	}
+
+	public SplitInquire getSplitInquire() {
+		return splitInquire;
+	}
+
+	public static class SplitArrive extends Base {
+
+	}
+
+	public static Signal splitArrive() {
+		Signal p = new Signal();
+		p.type = TYPE_SPLITARRIVE;
+		SplitArrive s = new SplitArrive();
+		p.splitArrive = s;
+		return p;
+	}
+
+	public static class SplitExecute extends Base {
+
+		List<String> splitValueList;
+
+		public List<String> getSplitValueList() {
+			return splitValueList;
+		}
+
+	}
+
+	public static Signal splitExecute(List<String> splitValues) {
+		Signal p = new Signal();
+		p.type = TYPE_SPLITEXECUTE;
+		SplitExecute s = new SplitExecute();
+		s.splitValueList = splitValues;
+		p.splitExecute = s;
+		return p;
+	}
+
+	public static class SplitInquire extends Base {
+
+	}
+
+	public static Signal splitInquire() {
+		Signal p = new Signal();
+		p.type = TYPE_SPLITINQUIRE;
+		SplitInquire s = new SplitInquire();
+		p.splitInquire = s;
+		return p;
+	}
+
+	public Signal() {
+		this.time = new Date();
+		this.stamp = this.time.getTime();
+	}
+
+	private String type;
+
+	public String getType() {
+		return type;
+	}
+
+	private Long stamp;
+
+	public Long getStamp() {
+		return stamp;
+	}
+
+	private Date time;
+
+	public Date getTime() {
+		return time;
+	}
+
+	public abstract static class Base {
+
+	}
+
+}

+ 9 - 0
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/SignalStack.java

@@ -0,0 +1,9 @@
+package com.x.processplatform.core.entity.log;
+
+import java.util.LinkedList;
+
+public class SignalStack extends LinkedList<Signal> {
+
+	private static final long serialVersionUID = -3971898583590304010L;
+
+}

+ 123 - 0
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/SignalStackLog.java

@@ -0,0 +1,123 @@
+package com.x.processplatform.core.entity.log;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.openjpa.persistence.Persistent;
+import org.apache.openjpa.persistence.jdbc.Index;
+import org.apache.openjpa.persistence.jdbc.Strategy;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.processplatform.core.entity.PersistenceProperties;
+
+@Entity
+@ContainerEntity(dumpSize = 100, type = ContainerEntity.Type.log, reference = ContainerEntity.Reference.soft)
+@Table(name = PersistenceProperties.Log.SignalStackLog.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.Log.SignalStackLog.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class SignalStackLog extends SliceJpaObject {
+
+	private static final long serialVersionUID = 3263767038182121907L;
+	private static final String TABLE = PersistenceProperties.Log.SignalStackLog.table;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	/* 以上为 JpaObject 默认字段 */
+
+	public void onPersist() throws Exception {
+		// nothing
+	}
+
+	public SignalStackLog() {
+		this.properties = new SignalStackLogProperties();
+	}
+
+	public SignalStackLog(String id, String job, SignalStack signalStack) {
+		this();
+		this.id = id;
+		this.job = job;
+		this.getProperties().setSignalStack(signalStack);
+	}
+
+	public SignalStackLogProperties getProperties() {
+		if (null == this.properties) {
+			this.properties = new SignalStackLogProperties();
+		}
+		return this.properties;
+	}
+
+	public void setProperties(SignalStackLogProperties properties) {
+		this.properties = properties;
+	}
+
+	public SignalStack getSignalStack() {
+		return this.getProperties().getSignalStack();
+	}
+
+	public void setSignalStack(SignalStack signalStack) {
+		this.getProperties().setSignalStack(signalStack);
+	}
+
+	public static final String job_FIELDNAME = "job";
+	@FieldDescribe("任务.")
+	@Column(length = JpaObject.length_id, name = ColumnNamePrefix + job_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + job_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String job;
+
+	public static final String work_FIELDNAME = "work";
+	@FieldDescribe("工作ID.")
+	@Column(length = JpaObject.length_id, name = ColumnNamePrefix + work_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + work_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String work;
+
+	public static final String properties_FIELDNAME = "properties";
+	// @Basic(fetch = FetchType.EAGER)
+	@FieldDescribe("属性对象存储字段.")
+	@Persistent(fetch = FetchType.EAGER)
+	@Strategy(JsonPropertiesValueHandler)
+	@Column(length = JpaObject.length_10M, name = ColumnNamePrefix + properties_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private SignalStackLogProperties properties;
+
+	public String getJob() {
+		return job;
+	}
+
+	public void setJob(String job) {
+		this.job = job;
+	}
+
+	public String getWork() {
+		return work;
+	}
+
+	public void setWork(String work) {
+		this.work = work;
+	}
+
+}

+ 23 - 0
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/log/SignalStackLogProperties.java

@@ -0,0 +1,23 @@
+package com.x.processplatform.core.entity.log;
+
+import com.x.base.core.entity.JsonProperties;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+public class SignalStackLogProperties extends JsonProperties {
+
+	private static final long serialVersionUID = 5194057760551594662L;
+	@FieldDescribe("型号栈.")
+	private SignalStack signalStack;
+
+	public SignalStack getSignalStack() {
+		if (this.signalStack == null) {
+			this.signalStack = new SignalStack();
+		}
+		return signalStack;
+	}
+
+	public void setSignalStack(SignalStack signalStack) {
+		this.signalStack = signalStack;
+	}
+
+}

+ 16 - 14
o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/ProcessingAttributes.java

@@ -5,10 +5,11 @@ import java.util.List;
 
 import com.google.gson.JsonElement;
 import com.x.base.core.project.annotation.FieldDescribe;
-import com.x.base.core.project.executor.Signal;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.gson.XGsonBuilder;
 import com.x.base.core.project.tools.StringTools;
+import com.x.processplatform.core.entity.log.Signal;
+import com.x.processplatform.core.entity.log.SignalStack;
 
 public class ProcessingAttributes extends GsonPropertyObject {
 
@@ -22,8 +23,6 @@ public class ProcessingAttributes extends GsonPropertyObject {
 	public static final String TYPE_SERVICE = "service";
 	private Integer loop = 1;
 
-	private transient Signal signal = null;
-
 	@FieldDescribe("强制从arrive开始")
 	private Boolean forceJoinAtArrive;
 
@@ -39,13 +38,20 @@ public class ProcessingAttributes extends GsonPropertyObject {
 	@FieldDescribe("当前处理人身份")
 	private String identity;
 
-	public ProcessingAttributes() {
-		this.series = StringTools.uniqueToken();
-		this.signal = new Signal();
+	private SignalStack signalStack = new SignalStack();
+
+	
+	public SignalStack getSignalStack() {
+		return signalStack;
+	}
+
+	public void push(Signal signal) {
+		this.signalStack.push(signal);
 	}
 
-	public Signal signal() {
-		return this.signal;
+	public ProcessingAttributes() {
+		this.series = StringTools.uniqueToken();
+		this.signalStack = new SignalStack();
 	}
 
 	private Boolean debugger = false;
@@ -175,14 +181,10 @@ public class ProcessingAttributes extends GsonPropertyObject {
 		this.identity = identity;
 	}
 
-	public ProcessingAttributes copyInstanceButSameSignal() {
+	public ProcessingAttributes copyInstancePointToSingletonSignalStack() {
 		ProcessingAttributes p = XGsonBuilder.convert(this, ProcessingAttributes.class);
-		p.signal(this.signal);
+		p.signalStack = this.signalStack;
 		return p;
 	}
 
-	private void signal(Signal signal) {
-		this.signal = signal;
-	}
-
 }

+ 0 - 52
o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/ProcessingSignal.java

@@ -1,52 +0,0 @@
-package com.x.processplatform.core.express;
-
-import java.util.List;
-
-import com.x.base.core.project.gson.GsonPropertyObject;
-
-public class ProcessingSignal extends GsonPropertyObject {
-
-	public ProcessingSignal() {
-
-	}
-
-	public static final String TYPE_SPLIT = "split";
-
-	private String type = "";
-
-	public String getType() {
-		return type;
-	}
-
-	private Split split = new Split();
-
-	public Split getSplit() {
-		if (null == split) {
-			this.split = new Split();
-		}
-		return this.split;
-	}
-
-	public static class Split {
-
-		List<String> splitValueList;
-
-		public List<String> getSplitValueList() {
-			return splitValueList;
-		}
-
-		public void setSplitValueList(List<String> splitValueList) {
-			this.splitValueList = splitValueList;
-		}
-	}
-
-	public static ProcessingSignal splitSignal(List<String> splitValues) {
-		ProcessingSignal p = new ProcessingSignal();
-		p.type = TYPE_SPLIT;
-		Split split = new Split();
-		split.setSplitValueList(splitValues);
-		p.split = split;
-		return p;
-	}
-
-}

+ 30 - 0
o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/service/processing/jaxrs/task/ActionProcessingWo.java

@@ -0,0 +1,30 @@
+package com.x.processplatform.core.express.service.processing.jaxrs.task;
+
+import com.x.processplatform.core.entity.content.Record;
+import com.x.processplatform.core.entity.log.SignalStack;
+
+public class ActionProcessingWo extends Record {
+
+	private static final long serialVersionUID = -8450939016187545724L;
+
+	private SignalStack signalStack;
+
+	private Boolean occurSignalStack;
+
+	public SignalStack getSignalStack() {
+		return signalStack;
+	}
+
+	public void setSignalStack(SignalStack signalStack) {
+		this.signalStack = signalStack;
+	}
+
+	public Boolean getOccurSignalStack() {
+		return occurSignalStack;
+	}
+
+	public void setOccurSignalStack(Boolean occurSignalStack) {
+		this.occurSignalStack = occurSignalStack;
+	}
+
+}

+ 22 - 0
o2server/x_processplatform_core_express/src/main/java/com/x/processplatform/core/express/service/processing/jaxrs/work/ActionProcessingSignalWo.java

@@ -0,0 +1,22 @@
+package com.x.processplatform.core.express.service.processing.jaxrs.work;
+
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.processplatform.core.entity.log.SignalStack;
+
+public class ActionProcessingSignalWo extends WoId {
+
+	private static final long serialVersionUID = 8851351880636501257L;
+
+	@FieldDescribe("流程信号栈.")
+	private SignalStack signalStack;
+
+	public SignalStack getSignalStack() {
+		return signalStack;
+	}
+
+	public void setSignalStack(SignalStack signalStack) {
+		this.signalStack = signalStack;
+	}
+
+}

+ 20 - 24
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/Processing.java

@@ -1,16 +1,20 @@
 package com.x.processplatform.service.processing;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 import org.apache.commons.collections4.list.SetUniqueList;
+import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
-import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.config.Config;
 import com.x.base.core.project.tools.ListTools;
 import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.log.SignalStackLog;
 import com.x.processplatform.core.express.ProcessingAttributes;
 import com.x.processplatform.service.processing.configurator.ProcessingConfigurator;
 
@@ -31,7 +35,7 @@ public class Processing extends BaseProcessing {
 			this.processingAttributes = processingAttributes;
 		}
 		if (this.processingAttributes.getLoop() > 64) {
-			throw new Exception("processing too many.");
+			throw new IllegalStateException("processing too many.");
 		}
 		this.entityManagerContainer = EntityManagerContainerFactory.instance().create();
 	}
@@ -41,10 +45,10 @@ public class Processing extends BaseProcessing {
 	}
 
 	public void processing(String workId, ProcessingConfigurator processingConfigurator) throws Exception {
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!11" + Processing.class);
 		try {
 			Work work = null;
-			work = this.entityManagerContainer().fetch(workId, Work.class, ListTools.toList(Work.workStatus_FIELDNAME));
+			work = this.entityManagerContainer().fetch(workId, Work.class,
+					ListTools.toList(Work.workStatus_FIELDNAME, Work.job_FIELDNAME));
 			if (null != work) {
 				switch (work.getWorkStatus()) {
 				case start:
@@ -63,17 +67,17 @@ public class Processing extends BaseProcessing {
 			/* workStatus is processing */
 			List<String> nextLoops = SetUniqueList.setUniqueList(new ArrayList<String>());
 			/* 强制从arrived开始 */
-			if (processingAttributes.ifForceJoinAtArrive()) {
+			if (BooleanUtils.isTrue(processingAttributes.ifForceJoinAtArrive())) {
 				workId = this.arrive(workId, processingConfigurator, processingAttributes);
 			}
-			if (!processingConfigurator.getJoinAtExecute()) {
+			if (BooleanUtils.isFalse(processingConfigurator.getJoinAtExecute())) {
 				workId = this.arrive(workId, processingConfigurator, processingAttributes);
 			}
 			if (StringUtils.isEmpty(workId)) {
 				return;
 			}
 			List<String> executed = null;
-			if (!processingAttributes.ifForceJoinAtInquire()) {
+			if (BooleanUtils.isFalse(processingAttributes.ifForceJoinAtInquire())) {
 				executed = this.execute(workId, processingConfigurator, processingAttributes);
 			} else {
 				/* 强制从inquire开始 */
@@ -90,21 +94,15 @@ public class Processing extends BaseProcessing {
 			}
 			processingAttributes.increaseLoop();
 			for (String str : nextLoops) {
-				if (StringUtils.isNotEmpty(str)) {
-					if (processingConfigurator.getContinueLoop()) {
-//						new Processing(processingAttributes, this.entityManagerContainer()).processing(str);
-//						new Processing(XGsonBuilder.convert(processingAttributes, ProcessingAttributes.class))
-//								.processing(str);
-						// clone processingAttributes 对象
-						new Processing(processingAttributes.copyInstanceButSameSignal()).processing(str);
-					}
+				if (StringUtils.isNotEmpty(str) && BooleanUtils.isTrue(processingConfigurator.getContinueLoop())) {
+					// clone processingAttributes 对象
+					new Processing(processingAttributes.copyInstancePointToSingletonSignalStack()).processing(str);
 				}
 			}
 		} catch (Exception e) {
-			throw new Exception("processing fialure.", e);
+			throw new IllegalStateException("processing fialure.", e);
 		} finally {
 			this.entityManagerContainer().close();
-			processingAttributes.signal().close();
 		}
 	}
 
@@ -167,7 +165,7 @@ public class Processing extends BaseProcessing {
 			/** 在内层的方法中进行提交,这里不需要再次进行提交,在内层提交是因为比如发送待办等要在提交后运行 */
 			return id;
 		} catch (Exception e) {
-			throw new Exception("processing arrive failure.", e);
+			throw new IllegalStateException("processing arrive failure.", e);
 		}
 	}
 
@@ -227,11 +225,10 @@ public class Processing extends BaseProcessing {
 			default:
 				break;
 			}
-			/** 在内层的方法中进行提交,这里不需要再次进行提交,在内层提交是因为比如发送待办等要在提交后运行 */
-			// this.entityManagerContainer.commit();
+			// 在内层的方法中进行提交,这里不需要再次进行提交,在内层提交是因为比如发送待办等要在提交后运行
 			return executed;
 		} catch (Exception e) {
-			throw new Exception("processing execute failure.", e);
+			throw new IllegalStateException("processing execute failure.", e);
 		}
 	}
 
@@ -289,11 +286,10 @@ public class Processing extends BaseProcessing {
 			default:
 				break;
 			}
-			/** 在内层的方法中进行提交,这里不需要再次进行提交,在内层提交是因为比如发送待办等要在提交后运行 */
-			// this.entityManagerContainer.commit();
+			// 在内层的方法中进行提交,这里不需要再次进行提交,在内层提交是因为比如发送待办等要在提交后运行
 			return inquired;
 		} catch (Exception e) {
-			throw new Exception("processing inquire failure.", e);
+			throw new IllegalStateException("processing inquire failure.", e);
 		}
 	}
 }

+ 43 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/ProcessingToProcessingSignalStack.java

@@ -0,0 +1,43 @@
+package com.x.processplatform.service.processing;
+
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.x.processplatform.core.entity.log.SignalStack;
+
+public class ProcessingToProcessingSignalStack extends ConcurrentHashMap<String, SignalStack> {
+
+	private static final String SPLIT = "#";
+
+	private static final long serialVersionUID = 5924230440506195407L;
+
+	public SignalStack open(String work, String series, SignalStack signalStack) {
+		return this.put(key(work, series), signalStack);
+	}
+
+	public Optional<SignalStack> find(String work, String series) {
+		return Optional.ofNullable(this.get(key(work, series)));
+	}
+
+	public void close(String work, String series) {
+		this.remove(key(work, series));
+	}
+
+	private String key(String work, String series) {
+		return work + SPLIT + series;
+	}
+
+//	@Test
+//	public void test() {
+//		ProcessingToProcessingSignalMapping m = new ProcessingToProcessingSignalMapping();
+//		Signal s1 = m.open("111", "222");
+//		System.out.println(s1);
+//		Signal s2 = m.open("111", "222");
+//		System.out.println(s2);
+//		System.out.println(s2==s1);		
+//		m.close("111", "222");
+//		m.close("111", "222");
+//		System.out.println(m.size());
+//	}
+
+}

+ 7 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/ThisApplication.java

@@ -33,6 +33,12 @@ public class ThisApplication {
 
 	public static final SyncEmbedQueue syncEmbedQueue = new SyncEmbedQueue();
 
+	private static ProcessingToProcessingSignalStack processingToProcessingSignalStack = new ProcessingToProcessingSignalStack();
+
+	public static ProcessingToProcessingSignalStack getProcessingToProcessingSignalStack() {
+		return processingToProcessingSignalStack;
+	}
+
 	public static Context context() {
 		return context;
 	}
@@ -69,6 +75,7 @@ public class ThisApplication {
 			if (BooleanUtils.isTrue(Config.processPlatform().getUrge().getEnable())) {
 				context.schedule(Urge.class, Config.processPlatform().getUrge().getCron());
 			}
+
 		} catch (Exception e) {
 			e.printStackTrace();
 		}

+ 40 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/ActionProcessingSignal.java

@@ -0,0 +1,40 @@
+package com.x.processplatform.service.processing.jaxrs.work;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.tools.ListTools;
+import com.x.processplatform.core.entity.log.Signal;
+import com.x.processplatform.core.entity.log.SignalStack;
+import com.x.processplatform.core.express.service.processing.jaxrs.work.ActionProcessingSignalWo;
+import com.x.processplatform.service.processing.ThisApplication;
+
+class ActionProcessingSignal extends BaseAction {
+
+	private static final List<String> EXPORTSIGNALS = ListTools.toList(Signal.TYPE_MANUALEXECUTE,
+			Signal.TYPE_SPLITEXECUTE);
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id, String series) throws Exception {
+
+		Thread.sleep(Config.processPlatform().getProcessingSignalThreshold());
+
+		Optional<SignalStack> optional = ThisApplication.getProcessingToProcessingSignalStack().find(id, series);
+
+		Wo wo = new Wo();
+		optional.ifPresent(
+				o -> o.stream().filter(s -> EXPORTSIGNALS.contains(s.getType())).forEach(wo.getSignalStack()::add));
+		optional.ifPresent(wo::setSignalStack);
+		ActionResult<Wo> result = new ActionResult<>();
+		result.setData(wo);
+		return result;
+	}
+
+	public static class Wo extends ActionProcessingSignalWo {
+		private static final long serialVersionUID = -3206075665001702872L;
+	}
+
+}

+ 19 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/WorkAction.java

@@ -105,6 +105,25 @@ public class WorkAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 
+	@JaxrsMethodDescribe(value = "流程信号.", action = ActionProcessingSignal.class)
+	@GET
+	@Path("{id}/series/{series}/processing/signal")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void processing(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作标识") @PathParam("id") String id,
+			@JaxrsParameterDescribe("串号") @PathParam("series") String series) {
+		ActionResult<ActionProcessingSignal.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionProcessingSignal().execute(effectivePerson, id, series);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
 	@JaxrsMethodDescribe(value = "删除单个工作.", action = ActionDelete.class)
 	@DELETE
 	@Path("{id}")

+ 7 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/agent/AgentProcessor.java

@@ -13,6 +13,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Agent;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -26,6 +27,8 @@ public class AgentProcessor extends AbstractAgentProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Agent agent) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.agentArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -35,6 +38,8 @@ public class AgentProcessor extends AbstractAgentProcessor {
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Agent agent) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.agentExecute());
 		List<Work> results = new ArrayList<>();
 		if (StringUtils.isNotEmpty(agent.getScript()) || StringUtils.isNotEmpty(agent.getScriptText())) {
 			CompiledScript compiledScript = aeiObjects.business().element().getCompiledScript(
@@ -52,6 +57,8 @@ public class AgentProcessor extends AbstractAgentProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Agent agent) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.agentInquire());
 		List<Route> results = new ArrayList<>();
 		Route o = aeiObjects.getRoutes().get(0);
 		results.add(o);

+ 24 - 18
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/begin/BeginProcessor.java

@@ -21,6 +21,7 @@ import com.x.processplatform.core.entity.content.Review;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Begin;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -34,7 +35,9 @@ public class BeginProcessor extends AbstractBeginProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Begin begin) throws Exception {
-		/* 创建创建者的review */
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.beginArrive());
+		// 创建创建者的review
 		String person = this.business().organization().person().get(aeiObjects.getWork().getCreatorPerson());
 		if (StringUtils.isNotEmpty(person)) {
 			aeiObjects.createReview(new Review(aeiObjects.getWork(), person));
@@ -49,11 +52,13 @@ public class BeginProcessor extends AbstractBeginProcessor {
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Begin begin) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.beginExecute());
 		List<Work> list = new ArrayList<>();
-		/** 如果是再次进入begin节点那么就不需要设置开始时间 */
+		// 如果是再次进入begin节点那么就不需要设置开始时间
 		if (aeiObjects.getWork().getStartTime() == null) {
 			aeiObjects.getWork().setStartTime(new Date());
-			/** 计算过期时间 */
+			// 计算过期时间
 			this.calculateExpire(aeiObjects);
 		}
 		list.add(aeiObjects.getWork());
@@ -72,6 +77,8 @@ public class BeginProcessor extends AbstractBeginProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Begin begin) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.beginInquire());
 		List<Route> list = new ArrayList<>();
 		Route o = aeiObjects.getRoutes().get(0);
 		list.add(o);
@@ -83,21 +90,20 @@ public class BeginProcessor extends AbstractBeginProcessor {
 	}
 
 	private void calculateExpire(AeiObjects aeiObjects) throws Exception {
-		if (aeiObjects.getActivityProcessingConfigurator().getCalculateExpire()) {
-			if (null != aeiObjects.getProcess().getExpireType()) {
-				switch (aeiObjects.getProcess().getExpireType()) {
-				case never:
-					this.expireNever(aeiObjects);
-					break;
-				case appoint:
-					this.expireAppoint(aeiObjects);
-					break;
-				case script:
-					this.expireScript(aeiObjects);
-					break;
-				default:
-					break;
-				}
+		if (BooleanUtils.isTrue(aeiObjects.getActivityProcessingConfigurator().getCalculateExpire())
+				&& (null != aeiObjects.getProcess().getExpireType())) {
+			switch (aeiObjects.getProcess().getExpireType()) {
+			case never:
+				this.expireNever(aeiObjects);
+				break;
+			case appoint:
+				this.expireAppoint(aeiObjects);
+				break;
+			case script:
+				this.expireScript(aeiObjects);
+				break;
+			default:
+				break;
 			}
 		}
 	}

+ 9 - 2
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/cancel/CancelProcessor.java

@@ -14,6 +14,7 @@ import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.ActivityType;
 import com.x.processplatform.core.entity.element.Cancel;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.core.express.ProcessingAttributes;
 import com.x.processplatform.service.processing.Processing;
 import com.x.processplatform.service.processing.processor.AeiObjects;
@@ -28,6 +29,8 @@ public class CancelProcessor extends AbstractCancelProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Cancel cancel) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.cancelArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -38,7 +41,9 @@ public class CancelProcessor extends AbstractCancelProcessor {
 
 	@Override
 	public List<Work> executing(AeiObjects aeiObjects, Cancel cancel) throws Exception {
-		/* 唯一work处理 */
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.cancelExecute());
+		// 唯一work处理
 		if (aeiObjects.getWorks().size() > 1) {
 			aeiObjects.getDeleteWorks().add(aeiObjects.getWork());
 			aeiObjects.getTasks().stream().filter(o -> StringUtils.equals(o.getWork(), aeiObjects.getWork().getId()))
@@ -78,7 +83,9 @@ public class CancelProcessor extends AbstractCancelProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Cancel cancel) throws Exception {
-		return new ArrayList<Route>();
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.cancelInquire());
+		return new ArrayList<>();
 	}
 
 	@Override

+ 10 - 7
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/choice/ChoiceProcessor.java

@@ -16,6 +16,7 @@ import com.x.base.core.project.script.ScriptFactory;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Choice;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -29,16 +30,20 @@ public class ChoiceProcessor extends AbstractChoiceProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Choice choice) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.choiceArrive());
 		return aeiObjects.getWork();
 	}
 
 	@Override
 	protected void arrivingCommitted(AeiObjects aeiObjects, Choice choice) throws Exception {
-//nothing
+		//nothing
 	}
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Choice choice) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.choiceExecute());
 		List<Work> results = new ArrayList<>();
 		results.add(aeiObjects.getWork());
 		return results;
@@ -46,23 +51,21 @@ public class ChoiceProcessor extends AbstractChoiceProcessor {
 
 	@Override
 	protected void executingCommitted(AeiObjects aeiObjects, Choice choice) throws Exception {
-//nothing
+		//nothing
 	}
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Choice choice) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.choiceInquire());
 		List<Route> results = new ArrayList<>();
-		/* 多条路由进行判断 */
+		// 多条路由进行判断
 		for (Route o : aeiObjects.getRoutes()) {
 			ScriptContext scriptContext = aeiObjects.scriptContext();
 			scriptContext.getBindings(ScriptContext.ENGINE_SCOPE).put(ScriptFactory.BINDING_NAME_ROUTE, o);
 			Object objectValue = aeiObjects.business().element()
 					.getCompiledScript(aeiObjects.getWork().getApplication(), o, Business.EVENT_ROUTE)
 					.eval(scriptContext);
-//			if (BooleanUtils.toBoolean(StringUtils.trimToNull(Objects.toString(obj))) == true) {
-//				results.add(o);
-//				break;
-//			}
 			if (BooleanUtils.isTrue(ScriptFactory.asBoolean(objectValue))) {
 				results.add(o);
 				break;

+ 7 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/delay/DelayProcessor.java

@@ -17,6 +17,7 @@ import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Delay;
 import com.x.processplatform.core.entity.element.DelayMode;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -30,6 +31,8 @@ public class DelayProcessor extends AbstractDelayProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Delay delay) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.delayArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -39,6 +42,8 @@ public class DelayProcessor extends AbstractDelayProcessor {
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Delay delay) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.delayExecute());
 		List<Work> results = new ArrayList<>();
 		Date limit = null;
 		if (null != delay.getDelayMode() && Objects.equals(DelayMode.until, delay.getDelayMode())) {
@@ -116,6 +121,8 @@ public class DelayProcessor extends AbstractDelayProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Delay delay) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.delayInquire());
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;

+ 8 - 1
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/embed/EmbedProcessor.java

@@ -20,6 +20,7 @@ import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Embed;
 import com.x.processplatform.core.entity.element.EmbedCreatorType;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.ThisApplication;
 import com.x.processplatform.service.processing.WrapScriptObject;
@@ -35,6 +36,8 @@ public class EmbedProcessor extends AbstractEmbedProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Embed embed) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.embedArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -44,6 +47,8 @@ public class EmbedProcessor extends AbstractEmbedProcessor {
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Embed embed) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.embedExecute());
 		AssginData assginData = new AssginData();
 		String targetApplication = embed.getTargetApplication();
 		String targetProcess = embed.getTargetProcess();
@@ -107,7 +112,9 @@ public class EmbedProcessor extends AbstractEmbedProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Embed embed) throws Exception {
-		/** 驱动上个环节新产生的work */
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.embedInquire());
+		// 驱动上个环节新产生的work
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;

+ 8 - 2
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/end/EndProcessor.java

@@ -18,6 +18,7 @@ import com.x.processplatform.core.entity.content.WorkCompleted;
 import com.x.processplatform.core.entity.element.End;
 import com.x.processplatform.core.entity.element.Form;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -31,6 +32,8 @@ public class EndProcessor extends AbstractEndProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, End end) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.endArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -41,7 +44,8 @@ public class EndProcessor extends AbstractEndProcessor {
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, End end) throws Exception {
-
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.endExecute());
 		List<Work> results = new ArrayList<>();
 
 		Work other = aeiObjects.getWorks().stream().filter(o -> {
@@ -152,7 +156,9 @@ public class EndProcessor extends AbstractEndProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, End end) throws Exception {
-		return new ArrayList<Route>();
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.endInquire());
+		return new ArrayList<>();
 	}
 
 	@Override

+ 7 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/invoke/InvokeProcessor.java

@@ -26,6 +26,7 @@ import com.x.base.core.project.tools.StringTools;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Invoke;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.ThisApplication;
 import com.x.processplatform.service.processing.WrapScriptObject;
@@ -41,11 +42,15 @@ public class InvokeProcessor extends AbstractInvokeProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Invoke invoke) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.invokeArrive());
 		return aeiObjects.getWork();
 	}
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Invoke invoke) throws Exception {
+		// 发送ProcessingSignal
+				aeiObjects.getProcessingAttributes().push(Signal.invokeExecute());
 		List<Work> results = new ArrayList<>();
 		switch (invoke.getInvokeMode()) {
 		case jaxws:
@@ -63,6 +68,8 @@ public class InvokeProcessor extends AbstractInvokeProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Invoke invoke) throws Exception {
+		// 发送ProcessingSignal
+				aeiObjects.getProcessingAttributes().push(Signal.invokeInquire());
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;

+ 11 - 1
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/manual/ManualProcessor.java

@@ -42,6 +42,7 @@ import com.x.processplatform.core.entity.element.Manual;
 import com.x.processplatform.core.entity.element.Route;
 import com.x.processplatform.core.entity.element.util.WorkLogTree;
 import com.x.processplatform.core.entity.element.util.WorkLogTree.Node;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -58,6 +59,8 @@ public class ManualProcessor extends AbstractManualProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Manual manual) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.manualArrive());
 		// 根据manual计算出来的活动处理人
 		List<String> identities = calculateTaskIdentities(aeiObjects, manual);
 		// 启用同类工作相同活动节点合并,如果有合并的工作,那么直接返回这个工作.
@@ -66,7 +69,7 @@ public class ManualProcessor extends AbstractManualProcessor {
 			return merge;
 		}
 		this.arrivingPassSame(aeiObjects, identities);
-		aeiObjects.getWork().setManualTaskIdentityList(new ArrayList<String>(identities));
+		aeiObjects.getWork().setManualTaskIdentityList(new ArrayList<>(identities));
 		return aeiObjects.getWork();
 	}
 
@@ -293,6 +296,10 @@ public class ManualProcessor extends AbstractManualProcessor {
 			aeiObjects.getWork().setManualTaskIdentityList(new ArrayList<String>(identities));
 		}
 
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes()
+				.push(Signal.manualExecute(Objects.toString(manual.getManualMode(), ""), identities));
+
 		switch (manual.getManualMode()) {
 		case single:
 			passThrough = this.single(aeiObjects, manual, identities);
@@ -323,6 +330,8 @@ public class ManualProcessor extends AbstractManualProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Manual manual) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.manualInquire());
 		List<Route> results = new ArrayList<>();
 		// 仅有单条路由
 		if (aeiObjects.getRoutes().size() == 1) {
@@ -342,6 +351,7 @@ public class ManualProcessor extends AbstractManualProcessor {
 				}
 			}
 		}
+
 		if (!results.isEmpty()) {
 			// 清理掉强制的指定的处理人
 			aeiObjects.getWork().getProperties().setManualForceTaskIdentityList(new ArrayList<String>());

+ 7 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/merge/MergeProcessor.java

@@ -13,6 +13,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Merge;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
 public class MergeProcessor extends AbstractMergeProcessor {
@@ -25,6 +26,8 @@ public class MergeProcessor extends AbstractMergeProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Merge merge) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.mergeArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -34,6 +37,8 @@ public class MergeProcessor extends AbstractMergeProcessor {
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Merge merge) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.mergeExecute());
 		List<Work> results = new ArrayList<>();
 		if (BooleanUtils.isNotTrue(aeiObjects.getWork().getSplitting())) {
 			/* 如果不是一个拆分文档,直接通过 */
@@ -214,6 +219,8 @@ public class MergeProcessor extends AbstractMergeProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Merge merge) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.mergeInquire());
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;

+ 10 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/message/MessageProcessor.java

@@ -9,6 +9,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Message;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.MessageFactory;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -22,15 +23,20 @@ public class MessageProcessor extends AbstractMessageProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Message message) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.messageArrive());
 		return aeiObjects.getWork();
 	}
 
 	@Override
 	protected void arrivingCommitted(AeiObjects aeiObjects, Message message) throws Exception {
+		// nothing
 	}
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Message message) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.embedExecute());
 		MessageFactory.activity_message(aeiObjects.getWork(), null);
 		List<Work> results = new ArrayList<>();
 		results.add(aeiObjects.getWork());
@@ -39,10 +45,13 @@ public class MessageProcessor extends AbstractMessageProcessor {
 
 	@Override
 	protected void executingCommitted(AeiObjects aeiObjects, Message message) throws Exception {
+		// nothing
 	}
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Message message) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.messageInquire());
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;
@@ -50,5 +59,6 @@ public class MessageProcessor extends AbstractMessageProcessor {
 
 	@Override
 	protected void inquiringCommitted(AeiObjects aeiObjects, Message message) throws Exception {
+		// nothing
 	}
 }

+ 11 - 7
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/parallel/ParallelProcessor.java

@@ -18,6 +18,7 @@ import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.content.WorkLog;
 import com.x.processplatform.core.entity.element.Parallel;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -31,6 +32,8 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Parallel parallel) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.parallelArrive());
 		logger.info(
 				"parallel arrvie processing, work title:{}, id:{}, actvity name:{}, id:{}, activityToken:{}, process name:{}, id{}.",
 				aeiObjects.getWork().getTitle(), aeiObjects.getWork().getId(), parallel.getName(), parallel.getId(),
@@ -41,11 +44,13 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 
 	@Override
 	protected void arrivingCommitted(AeiObjects aeiObjects, Parallel parallel) throws Exception {
-//nothing
+		// nothing
 	}
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Parallel parallel) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.parallelExecute());
 		List<Work> results = new ArrayList<>();
 		aeiObjects.getWork().setSplitting(true);
 		aeiObjects.getWork().setSplitToken(StringTools.uniqueToken());
@@ -74,9 +79,6 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 			if (BooleanUtils.isTrue(ScriptFactory.asBoolean(objectValue))) {
 				routes.add(o);
 			}
-//			if (BooleanUtils.toBoolean(StringUtils.trimToNull(Objects.toString(objectValue))) == true) {
-//				routes.add(o);
-//			}
 		}
 
 		for (int i = 0; i < routes.size(); i++) {
@@ -89,7 +91,7 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 				Work work = new Work(aeiObjects.getWork());
 				work.setDestinationRoute(route.getId());
 				work.setDestinationRouteName(route.getName());
-				/* 创建新的Token */
+				// 创建新的Token
 				WorkLog workLog = new WorkLog(mainWorkLog);
 				workLog.setWork(work.getId());
 				aeiObjects.getCreateWorks().add(work);
@@ -102,11 +104,13 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 
 	@Override
 	protected void executingCommitted(AeiObjects aeiObjects, Parallel parallel) throws Exception {
-		//nothing
+		// nothing
 	}
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Parallel parallel) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.parallelInquire());
 		List<Route> results = new ArrayList<>();
 		aeiObjects.getRoutes().stream().forEach(o -> {
 			if (StringUtils.equals(o.getId(), aeiObjects.getWork().getDestinationRoute())) {
@@ -125,6 +129,6 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 
 	@Override
 	protected void inquiringCommitted(AeiObjects aeiObjects, Parallel parallel) throws Exception {
-		//nothing
+		// nothing
 	}
 }

+ 12 - 6
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/service/ServiceProcessor.java

@@ -14,6 +14,7 @@ import com.x.base.core.project.script.ScriptFactory;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Route;
 import com.x.processplatform.core.entity.element.Service;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -29,20 +30,23 @@ public class ServiceProcessor extends AbstractServiceProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Service service) throws Exception {
-		/** 清空上一次调用值 */
-		aeiObjects.getWork().getProperties().setServiceValue(new LinkedHashMap<String, Object>());
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.serviceArrive());
+		// 清空上一次调用值
+		aeiObjects.getWork().getProperties().setServiceValue(new LinkedHashMap<>());
 		return aeiObjects.getWork();
 	}
 
 	@Override
 	protected void arrivingCommitted(AeiObjects aeiObjects, Service service) throws Exception {
-	 // Do nothing
+		// Do nothing
 	}
 
 	@Override
 	protected List<Work> executing(AeiObjects aeiObjects, Service service) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.parallelExecute());
 		List<Work> results = new ArrayList<>();
-
 		boolean passThrough = false;
 		if (StringUtils.isNotEmpty(service.getScript()) || StringUtils.isNotEmpty(service.getScriptText())) {
 			ScriptContext scriptContext = aeiObjects.scriptContext();
@@ -63,11 +67,13 @@ public class ServiceProcessor extends AbstractServiceProcessor {
 
 	@Override
 	protected void executingCommitted(AeiObjects aeiObjects, Service service) throws Exception {
-	// Do nothing
+		// Do nothing
 	}
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Service service) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.parallelInquire());
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;
@@ -75,6 +81,6 @@ public class ServiceProcessor extends AbstractServiceProcessor {
 
 	@Override
 	protected void inquiringCommitted(AeiObjects aeiObjects, Service service) throws Exception {
-	// Do nothing
+		// Do nothing
 	}
 }

+ 7 - 5
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/split/SplitProcessor.java

@@ -17,7 +17,7 @@ import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.content.WorkLog;
 import com.x.processplatform.core.entity.element.Route;
 import com.x.processplatform.core.entity.element.Split;
-import com.x.processplatform.core.express.ProcessingSignal;
+import com.x.processplatform.core.entity.log.Signal;
 import com.x.processplatform.service.processing.Business;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
@@ -31,6 +31,8 @@ public class SplitProcessor extends AbstractSplitProcessor {
 
 	@Override
 	protected Work arriving(AeiObjects aeiObjects, Split split) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.splitArrive());
 		return aeiObjects.getWork();
 	}
 
@@ -51,10 +53,8 @@ public class SplitProcessor extends AbstractSplitProcessor {
 			throw new ExceptionSplitEmptySplitValue(split.getName(), aeiObjects.getWork().getTitle(),
 					aeiObjects.getWork().getId(), aeiObjects.getWork().getJob());
 		}
-		// 如果发送值超过阈值那么发送ProcessingSingal
-		if (splitValues.size() >= Config.processPlatform().getProcessingSignal().getSplitThreshold()) {
-			aeiObjects.getProcessingAttributes().signal().write(gson.toJson(ProcessingSignal.splitSignal(splitValues)));
-		}
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.splitExecute(splitValues));
 		// 先将当前文档标志拆分值
 		aeiObjects.getWork().setSplitValue(splitValues.get(0));
 		aeiObjects.getWork().getSplitValueList().add(splitValues.get(0));
@@ -98,6 +98,8 @@ public class SplitProcessor extends AbstractSplitProcessor {
 
 	@Override
 	protected List<Route> inquiring(AeiObjects aeiObjects, Split split) throws Exception {
+		// 发送ProcessingSignal
+		aeiObjects.getProcessingAttributes().push(Signal.splitInquire());
 		List<Route> results = new ArrayList<>();
 		results.add(aeiObjects.getRoutes().get(0));
 		return results;