在windchill中队列分:排程,汇聚,进程
进程:我们通常在需要立即执行的任务,队列一般以业务模块+ProcessQueue结尾,如commonProcessQueue;
排程:我们通常在需要计划性执行某些任务时使用,队列一般以业务名称+ScheduleQueue,如commonScheduleQueue
汇聚:用的比较少,理解为系统本身相关的任务,WfPropagationQueue,DeleteCompletedWorkItemsQueue,WfUserWorkQueue等任务
下面我们介绍一下如何通过代码获取队列
public static ProcessingQueue getQueue(final String queueName) throws WTException {
ProcessingQueue processingQueue = QueueHelper.manager.getQueue(queueName);
String user = "";
try {
user = SessionHelper.manager.getPrincipal().getName();
SessionHelper.manager.setAdministrator();
if (processingQueue == null) {
processingQueue = QueueHelper.manager.createQueue(queueName);
}
if (!processingQueue.isEnabled()) {
QueueHelper.manager.enableQueue(processingQueue, true);
QueueHelper.manager.startQueue(processingQueue);
}
} finally {
if (StringUtils.isNotBlank(user)) {
SessionHelper.manager.setPrincipal(user);
}
}
return processingQueue;
}
如何添加一个队列条目
public static boolean addEntry(String queueName,String methodName,
String className, Class[] argsType, Object[] args)
throws RemoteException, InvocationTargetException, WTException{
if (!RemoteMethodServer.ServerFlag) {
try {
Class[] argType = {String.class,String.class,Class[].class,Object[].class };
Object[] arg = { methodName,className,argsType,args };
return (Boolean)RemoteMethodServer.getDefault().invoke("addEntry",
CUReferenceUtil.class.getName(), null,argType,arg);
} catch (Exception e) {
e.printStackTrace();
}
} else {
String user = "";
try {
user = SessionHelper.manager.getPrincipal().getName();
SessionHelper.manager.setAdministrator();
ProcessingQueue queue = getQueue(queueName);
QueueEntry entry = queue.addEntry(SessionHelper.manager.getAdministrator(),
methodName, className, argsType, args);
logger.info(queueName + "添加条目完毕>>>>>>>>>>>>>>>>");
if (entry != null) {
return true;
}
} finally {
if (StringUtils.isNotBlank(user)) {
SessionHelper.manager.setPrincipal(user);
}
}
}
return false;
}
在实际业务场景中我们会用到队列池,通常是在需要处理大批量业务数据且并发的场景:
如现在我需要做一个导出某个业务流程报表的业务,流程评审对象部件能卷积很多子项,每个子项需要导出一个文件,我们改如何做
public static void createBOMReportWithWTDocument(Set ha, String ecrNmber, String processid) throws Exception {
System.out.println(">>>>createBOMReportWithWTDocument-GSCR流程报表 ecrNmber[" +ecrNmber + "] SBA总数=" + ha.size());
int sbaCount = ha.size();
if (sbaCount == 0 || StringUtils.isBlank(ecrNmber)) {
return;
}
//查看系统中GSCR队列中等待的条目数
int initGscrProcessQueueCount =10;
Map gscrProcessQueuePool = new HashMap();
for (int gscrIndex = 0; gscrIndex > allGscrProcessQueue = new ArrayList>(
gscrProcessQueuePool.entrySet());
Collections.sort(allGscrProcessQueue, new Comparator>() {
public int compare(Map.Entry o1, Map.Entry o2) {
return (o1.getValue() - o2.getValue());
}
});
//当前流程总共需要导报表的数据除以报表导出队列总数,计算平均每个队列需要分配数量
double average = ext.source.gscr.sap.GSCRWorkflowUtility.round(sbaCount, initGscrProcessQueueCount, 1);
// 根据等待条目最少,决定有限将队列条目择优先放在哪一个队列中
Class[] argType = { String.class, String.class, String.class };
addedEntry(ha, ecrNmber, allGscrProcessQueue, average, argType);
}
public static double round(int v1, int v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("此参数错误");
}
BigDecimal one = new BigDecimal(Double.toString(v1));
BigDecimal two = new BigDecimal(Double.toString(v2));
return one.divide(two, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
通过命令行的方式查看队列,创建队列,设置分组等:
在windchill shell中我们可以输入:windchill wt.queue.QueueManager
有时候创建队列会提示已经超过系统最大数量,我们可通过增加如下配置来实现:
1) windchill shell中执行命令设置wt.queue.max.processQueues最大值:
xconfmanager -s wt.queue.max.processQueues=1000 -t /codebase/wt.properties –p
重新设置队列为SEVERE状态就可以重新执行的逻辑:
/**
* 重置队列条目的状态为指定状态
* @param entryNumber 条目编号
* @param targetState 目标状态,默认为FAILED
* @throws Exception
*/
public static void resetEntryStateToServer(String entryNumber, String targetState) throws Exception{
CSCDB cscdb = null;
PreparedStatement prep = null;
try {
cscdb = new CSCDB();
Connection connection = cscdb.getConnection();
connection.setAutoCommit(false);
String sql4RestEntryState = "";
if(StringUtils.isBlank(entryNumber)){
return;
}
entryNumber = entryNumber.trim();
if(StringUtils.isNotBlank(targetState)){
targetState = targetState.trim();
sql4RestEntryState = "update wcadmin.queueentry t set t.codec5='SEVERE' where t.entrynumber=?";
prep = connection.prepareStatement(sql4RestEntryState);
prep.setString(1, targetState.toUpperCase());
prep.setString(2, entryNumber);
}else{
sql4RestEntryState = "update wcadmin.queueentry t set t.codec5='FAILED' where t.entrynumber=?";
prep = connection.prepareStatement(sql4RestEntryState);
prep.setString(1, entryNumber);
}
prep.executeUpdate();
cscdb.commit();
} catch (Exception e) {
e.printStackTrace();
cscdb.rollback();
throw new Exception("Modify queueentry failure");
} finally {
cscdb.close();
}
}
移动某个processQueue条目到指定的ProcessQueue
/**
* 移动某个processQueue条目到指定的ProcessQueue
* @param afterQueueName 指定队列名称
* @param beforeQueueName 之前队列名称
* @param entryNumber 条目编号
* @throws SQLException
* @throws Exception
* @author wonly.wu 2018-08-06
*/
public static void moveEntry2TargetQueue(String afterQueueName,String beforeQueueName,String entryNumber) throws SQLException, Exception{
String sql4RestEntryQueueName = "";
if(StringUtils.isNotBlank(afterQueueName)){
afterQueueName = afterQueueName.trim();
}
if(StringUtils.isNotBlank(entryNumber)){
entryNumber = entryNumber.trim();
}
CSCDB cscdb = null;
PreparedStatement prep = null;
try {
cscdb = new CSCDB();
Connection connection = cscdb.getConnection();
connection.setAutoCommit(false);
if(StringUtils.isBlank(beforeQueueName)){
sql4RestEntryQueueName = "update wcadmin.queueentry t set t.ida3a5=(select q.ida2a2 from wcadmin.processingqueue q where q.name = ?) where t.entrynumber=?";
prep = connection.prepareStatement(sql4RestEntryQueueName);
prep.setString(1, afterQueueName);
prep.setString(2, entryNumber);
}else{
sql4RestEntryQueueName ="update wcadmin.queueentry t set t.ida3a5=(select q.ida2a2 from wcadmin.processingqueue q where q.name = ?) where t.ida3a5 = (select q.ida2a2 from wcadmin.processingqueue q where q.name = ?)";
prep = connection.prepareStatement(sql4RestEntryQueueName);
prep.setString(1, afterQueueName);
prep.setString(2, beforeQueueName);
}
prep.executeUpdate();
cscdb.commit();
} catch (Exception e) {
e.printStackTrace();
cscdb.rollback();
throw new Exception("Modify queueentry failure");
} finally {
cscdb.close();
}
}