<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://m.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)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久草视频在线免费看| xxxxx做受大片视频免费| a毛片免费播放全部完整| 国产精品99久久免费| 亚洲 暴爽 AV人人爽日日碰| 男女做羞羞的事视频免费观看无遮挡| 中文字幕亚洲综合精品一区| 99精品国产成人a∨免费看| 亚洲精品福利视频| 亚洲免费网站在线观看| 大地资源网高清在线观看免费| 青青青国产在线观看免费网站 | 麻豆高清免费国产一区| 久久亚洲私人国产精品vA| 日韩精品极品视频在线观看免费 | ssswww日本免费网站片| 亚洲男人天堂2020| 亚洲人成网站在线观看播放动漫 | 破了亲妺妺的处免费视频国产| 男男gvh肉在线观看免费| 亚洲性久久久影院| 国产精品免费福利久久| tom影院亚洲国产一区二区| 午夜毛片不卡免费观看视频| 国产精品亚洲专区在线播放 | 亚洲成av人片一区二区三区| 精品一区二区三区免费观看| 国产精品四虎在线观看免费 | 久久综合给合久久国产免费 | 亚洲香蕉久久一区二区三区四区| 国内大片在线免费看| 全部一级一级毛片免费看| 亚洲精品无码mv在线观看网站 | 亚洲va在线va天堂成人| 四虎精品亚洲一区二区三区| 久久精品免费观看国产| 亚洲中文字幕乱码熟女在线| 亚洲综合色区在线观看| 24小时日本电影免费看| 黄页网址在线免费观看| 久久精品国产亚洲av影院|