<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 193,  comments - 520,  trackbacks - 0
      整體來說實現(xiàn)的非常清晰:
      1、引擎解析流程定義xml時,給相應的事件掛接上create-timer 和 cancel-timer動作
      2、流程實例實際運轉時,create-timer動作在相應事件觸發(fā)時執(zhí)行
      3、create-timer在job表里插入相應時間job記錄,給該job記錄附上計算完畢的執(zhí)行時間
      4、JobExecutorServlet在后臺啟動一到多個JobExecutorThread線程
      5、JobExecutorThread線程不停的每隔一段時間對job表掃描一次,找出需要執(zhí)行的job記錄,執(zhí)行之
      6、只執(zhí)行一次的job記錄,執(zhí)行完畢后刪除之;重復執(zhí)行的job記錄,寫入新的執(zhí)行時間,更新之
      7、相應事件觸發(fā)cancel-timer動作,將對應job記錄從job表里刪除
      下面具體用代碼來說話(掛接到node節(jié)點):
      1、引擎解析流程定義xml 
      JpdlXmlReader.java 
      
    protected void readNodeTimer(Element timerElement, Node node) {
        String name 
    = timerElement.attributeValue("name", node.getName());
       
        CreateTimerAction createTimerAction 
    = new CreateTimerAction();
        createTimerAction.read(timerElement, 
    this);
        createTimerAction.setTimerName(name);
        createTimerAction.setTimerAction(readSingleAction(timerElement));
        addAction(node, Event.EVENTTYPE_NODE_ENTER, createTimerAction);
       
        CancelTimerAction cancelTimerAction 
    = new CancelTimerAction();
        cancelTimerAction.setTimerName(name);
        addAction(node, Event.EVENTTYPE_NODE_LEAVE, cancelTimerAction);
      }

      可以看到,引擎把xml中timer節(jié)點解析成了兩個ACTION:CreateTimerAction和CancelTimerAction
      CreateTimerAction會在進入該節(jié)點時觸發(fā),而CancelTimerAction會在令牌離開該節(jié)點時觸發(fā)。
      2、看看CreateTimerAction和CancelTimerAction究竟在做些什么
      CreateTimerAction.java
       
    public void execute(ExecutionContext executionContext) throws Exception {
        Timer timer 
    = createTimer(executionContext);
        SchedulerService schedulerService 
    = (SchedulerService) Services.getCurrentService(Services.SERVICENAME_SCHEDULER);
        schedulerService.createTimer(timer);
      }

      很明顯,是通過一個職責集中的schedulerService向job表中插入了一條job記錄,注意到這個方法:
      protected Timer createTimer(ExecutionContext executionContext) {
        Timer timer 
    = new Timer(executionContext.getToken());
        .
        
    if (dueDate!=null) {
          Duration duration 
    = new Duration(dueDate);
          Date dueDateDate 
    = businessCalendar.add( new Date(), duration );
          timer.setDueDate(dueDateDate);
        }
        .
       
        
    return timer;
      }

      這里利用JBPM提供的工作時間計算組件計算了job的執(zhí)行時間。
      CancelTimerAction就很簡單了,刪除相應的job記錄。
      CancelTimerAction.java
      
    public void execute(ExecutionContext executionContext) throws Exception {
        SchedulerService schedulerService 
    = (SchedulerService) Services.getCurrentService(Services.SERVICENAME_SCHEDULER);
        schedulerService.deleteTimersByName(timerName, executionContext.getToken());
      }

      3、JobExecutorServlet是干什么的
      啟動線程
      public void init() throws ServletException {
        .
        jbpmConfiguration.startJobExecutor();
      }

      4、線程是如何工作
      public void run() {
        
    try {
          currentIdleInterval 
    = idleInterval;
          
    while (isActive) {
            
    try {
              Collection acquiredJobs 
    = acquireJobs();   //從job表里獲得將要執(zhí)行的job記錄

              
    if (! acquiredJobs.isEmpty()) {    //如果記錄不為空,則開始執(zhí)行
                Iterator iter = acquiredJobs.iterator();
                
    while (iter.hasNext() && isActive) {
                  Job job 
    = (Job) iter.next();
                  executeJob(job);             
    //執(zhí)行
                }

              } 
    else { // no jobs acquired     //如果沒有可執(zhí)行的job,則等待一段時間
                if (isActive) {
                  
    long waitPeriod = getWaitPeriod();  //等待的時間是找出即將執(zhí)行的job離現(xiàn)在最近的時間間隔
                  if (waitPeriod>0) {
                    
    synchronized(jobExecutor) {
                      jobExecutor.wait(waitPeriod);
                    }
                  }
                }
              }
             
             .
        } 
    catch (Throwable t) {
          t.printStackTrace();
        } 
    finally {
          log.info(getName()
    +" leaves cyberspace");
        }
      }

      看看實際執(zhí)行的方法
      protected void executeJob(Job job) {
        JbpmContext jbpmContext 
    = jbpmConfiguration.createJbpmContext();
        
    try {
          JobSession jobSession 
    = jbpmContext.getJobSession();
          job 
    = jobSession.loadJob(job.getId());

          
    try {
            log.debug(
    "executing job "+job);
            
    if (job.execute(jbpmContext)) {    //交由Job對象本身去完成執(zhí)行的邏輯,并決定是否刪除job記錄
              jobSession.deleteJob(job);
            }
                .
      }

      5、著重關注Time對象
      在上面我們看到實際執(zhí)行的代碼是job.execute(jbpmContext);
      Time 是Job的子類,看看它的實現(xiàn):
      public boolean execute(JbpmContext jbpmContext) throws Exception {
        
    boolean deleteThisJob = true;       //執(zhí)行完畢后是否刪除job記錄

        ExecutionContext executionContext 
    = new ExecutionContext(token);
        executionContext.setTimer(
    this);

        
    if (taskInstance!=null) {
          executionContext.setTaskInstance(taskInstance);
        }

        
    // 觸發(fā)timer事件
        if (graphElement!=null) {
          graphElement.fireAndPropagateEvent(Event.EVENTTYPE_TIMER, executionContext);
        }

        
    // 如果timer節(jié)點上掛有action則執(zhí)行之
        if (action!=null) {
          
    try {
            log.debug(
    "executing timer '"+this+"'");
            action.execute(executionContext);
          } 
    catch (Exception actionException) {
          .
            }

        
    // 如果定義了transition屬性,則流程順著定義的路徑流轉
        if ( (transitionName!=null)
             
    && (exception==null// and if no unhandled exception occurred during the action 
           ) {
          
    if (token.getNode().hasLeavingTransition(transitionName)) {
            token.signal(transitionName);
          }
        }
       
        
    // 如果定義了repeat屬性則job記錄不容許刪除,同時計算新的執(zhí)行時間
        if (repeat!=null) {
          deleteThisJob 
    = false;

          
    while (dueDate.getTime()<=System.currentTimeMillis()) {
            dueDate 
    = businessCalendar
                  .add(dueDate,
                    
    new Duration(repeat));
          }
          log.debug(
    "updated timer for repetition '"+this+"' in '"+(dueDate.getTime()-System.currentTimeMillis())+"' millis");
        }
       
        
    return deleteThisJob;
      }




    http://www.tkk7.com/ronghao 榮浩原創(chuàng),轉載請注明出處:)
    posted on 2007-06-22 17:13 ronghao 閱讀(1947) 評論(0)  編輯  收藏 所屬分類: 工作流jbpm3
    <2007年6月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    關注工作流和企業(yè)業(yè)務流程改進?,F(xiàn)就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

    常用鏈接

    留言簿(38)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 日本激情猛烈在线看免费观看| 国产精品免费视频一区| aa午夜免费剧场| 亚洲中文字幕无码av| 亚洲国产精品一区二区久久| 亚洲国产成人精品女人久久久| 免费人成视频在线| 91福利免费视频| 成人网站免费看黄A站视频| 麻豆一区二区三区蜜桃免费| 亚洲依依成人亚洲社区| 亚洲乱码一二三四五六区| 亚洲免费在线视频| 亚洲成AV人片在线观看无 | 久久久亚洲欧洲日产国码二区| 久久亚洲色一区二区三区| 亚洲A∨午夜成人片精品网站| 成人毛片免费播放| 97无码免费人妻超级碰碰夜夜| 1000部拍拍拍18勿入免费凤凰福利| 最近2019中文免费字幕在线观看| 国产日韩AV免费无码一区二区三区| 免费国产va视频永久在线观看| 黄色三级三级免费看| 亚洲国产成人AV网站| 国产亚洲人成在线影院| 精品久久久久久久久亚洲偷窥女厕| 亚洲区日韩精品中文字幕| 亚洲熟妇无码八V在线播放| 亚洲日韩国产精品乱-久| 亚洲国产日韩精品| 美女视频黄免费亚洲| 亚洲最大的成人网| 亚洲成a∨人片在无码2023| 国产亚洲福利精品一区二区| 猫咪免费观看人成网站在线| 免费无码婬片aaa直播表情| h片在线观看免费| 国产无遮挡无码视频免费软件| a级片免费观看视频| 精品熟女少妇a∨免费久久|