File Source: JPAThreadManagerImpl.java

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   *  contributor license agreements.  The ASF licenses this file to You
     4   * under the Apache License, Version 2.0 (the "License"); you may not
     5   * use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.  For additional information regarding
    15   * copyright in this work, please see the NOTICE file in the top level
    16   * directory of this distribution.
    17   */
    18  
    19  package org.apache.roller.weblogger.business.jpa;
    20  
    21  import java.sql.Timestamp;
    22  import java.util.Date;
    23  import javax.persistence.NoResultException;
    24  import javax.persistence.Query;
    25  import org.apache.commons.logging.Log;
    26  import org.apache.commons.logging.LogFactory;
    27  import org.apache.roller.util.DateUtil;
    28  import org.apache.roller.weblogger.WebloggerException;
    29  import org.apache.roller.weblogger.business.Weblogger;
    30  import org.apache.roller.weblogger.business.runnable.ThreadManagerImpl;
    31  import org.apache.roller.weblogger.business.runnable.RollerTask;
    32  import org.apache.roller.weblogger.pojos.TaskLock;
    33  
    34  
    35  /**
    36   * JPA implementation of the TaskLockManager interface.
    37   *
    38   * This implementation extends the base ThreadManagerImpl class and provides
    39   * locking abilities which are managed through the database.
    40   */
    41  @com.google.inject.Singleton
    42  public class JPAThreadManagerImpl extends ThreadManagerImpl {
    43  
             /* 
    P/P       *  Method: org.apache.roller.weblogger.business.jpa.JPAThreadManagerImpl__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              */
    44      private static final Log log = LogFactory.getLog(JPAThreadManagerImpl.class);
    45  
    46      private final Weblogger roller;
    47      private final JPAPersistenceStrategy strategy;
    48  
    49  
    50      @com.google.inject.Inject
    51      protected JPAThreadManagerImpl(Weblogger roller, JPAPersistenceStrategy strat) {
                 /* 
    P/P           *  Method: void org.apache.roller.weblogger.business.jpa.JPAThreadManagerImpl(Weblogger, JPAPersistenceStrategy)
                  * 
                  *  Presumptions:
                  *    org.apache.commons.logging.LogFactory:getLog(...)@44 != null
                  * 
                  *  Postconditions:
                  *    this.roller == roller
                  *    init'ed(this.roller)
                  *    this.schedulerThread == null
                  *    init'ed(this.serviceScheduler)
                  *    this.strategy == strat
                  *    init'ed(this.strategy)
                  */
    52          super();
    53  
    54          log.debug("Instantiating JPA Thread Manager");
    55  
    56          this.roller = roller;
    57          this.strategy = strat;
    58      }
    59  
    60  
    61      /**
    62       * Try to aquire a lock for a given RollerTask.
    63       */
    64      @Override
    65      public boolean registerLease(RollerTask task) {
    66          
                 /* 
    P/P           *  Method: bool registerLease(RollerTask)
                  * 
                  *  Preconditions:
                  *    task != null
                  *    (soft) init'ed(task.clientId)
                  *    (soft) init'ed(task.leaseTime)
                  *    (soft) init'ed(task.startTimeDesc)
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    javax.persistence.EntityManager:createNamedQuery(...)@301 != null
                  *    org.apache.commons.logging.LogFactory:getLog(...)@44 != null
                  *    org.apache.roller.util.DateUtil:getStartOfDay(...)@95 != null
                  *    org.apache.roller.util.DateUtil:getStartOfHour(...)@98 != null
                  *    org.apache.roller.util.DateUtil:getStartOfMinute(...)@101 != null
                  *    ...
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@93: {0}, {1}
                  *    java.lang.String:equals(...)@96: {0}, {1}
                  *    org.apache.commons.logging.Log:isDebugEnabled(...)@104: {0}, {1}
                  */
    67          log.debug("Attempting to register lease for task - "+task.getName());
    68          
    69          // keep a copy of the current time
    70          Date currentTime = new Date();
    71          
    72          // query for existing lease record first
    73          TaskLock taskLock = null;
    74          try {
    75              taskLock = getTaskLockByName(task.getName());
    76              if(taskLock == null) {
    77                  log.warn("Cannot acquire lease when no tasklock record exists for task - "+task.getName());
    78              }
    79          } catch (WebloggerException ex) {
    80              log.warn("Error getting TaskLock", ex);
    81              return false;
    82          }
    83  
    84          // try to acquire lease
    85          if(taskLock != null) try {
    86              // calculate lease expiration time
    87              Date leaseExpiration = taskLock.getLeaseExpiration();
    88              
    89              // calculate run time for task, this is expected time, not actual time
    90              // i.e. if a task is meant to run daily at midnight this should
    91              // reflect 00:00:00 on the current day
+   92              Date runTime = currentTime;
    93              if("startOfDay".equals(task.getStartTimeDesc())) {
    94                  // start of today
    95                  runTime = DateUtil.getStartOfDay(currentTime);
    96              } else if("startOfHour".equals(task.getStartTimeDesc())) {
    97                  // start of this hour
    98                  runTime = DateUtil.getStartOfHour(currentTime);
    99              } else {
   100                  // start of this minute
   101                  runTime = DateUtil.getStartOfMinute(currentTime);
   102              }
   103              
   104              if(log.isDebugEnabled()) {
   105                  log.debug("last run = "+taskLock.getLastRun());
   106                  log.debug("new run time = "+runTime);
   107                  log.debug("last acquired = "+taskLock.getTimeAquired());
   108                  log.debug("time leased = "+taskLock.getTimeLeased());
   109                  log.debug("lease expiration = "+leaseExpiration);
   110              }
   111  
   112              Query q = strategy.getNamedUpdate(
   113                      "TaskLock.updateClient&Timeacquired&Timeleased&LastRunByName&Timeacquired");
   114              q.setParameter(1, task.getClientId());
   115              q.setParameter(2, Integer.valueOf(task.getLeaseTime()));
   116              q.setParameter(3, new Timestamp(runTime.getTime()));
   117              q.setParameter(4, task.getName());
   118              q.setParameter(5, taskLock.getTimeAquired());
   119              q.setParameter(6, new Timestamp(leaseExpiration.getTime()));
   120              int result = q.executeUpdate();
   121              
   122              if(result == 1) {
   123                  return true;
   124              }
   125  
   126          } catch (Exception e) {
   127              log.warn("Error obtaining lease, assuming race condition.", e);
   128              return false;
   129          }
   130  
   131          return false;
   132      }
   133  
   134  
   135      /**
   136       * Try to release the lock for a given RollerTask.
   137       */
   138      @Override
   139      public boolean unregisterLease(RollerTask task) {
   140  
   141          // query for existing lease record first
                 /* 
    P/P           *  Method: bool unregisterLease(RollerTask)
                  * 
                  *  Preconditions:
                  *    (soft) task != null
                  *    (soft) init'ed(task.clientId)
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    javax.persistence.EntityManager:createNamedQuery(...)@301 != null
                  *    org.apache.commons.logging.LogFactory:getLog(...)@44 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    javax.persistence.Query:executeUpdate(...)@162: {-231..0, 2..232-1}, {1}
                  */
   142          TaskLock taskLock = null;
   143          try {
   144              taskLock = this.getTaskLockByName(task.getName());
   145  
   146              if(taskLock == null) {
   147                  return false;
   148              }
   149  
   150          } catch (WebloggerException ex) {
   151              log.warn("Error getting TaskLock", ex);
   152              return false;
   153          }
   154  
   155          // try to release lease, just set lease time to 0
   156          try {
   157              Query q = strategy.getNamedUpdate(
   158                      "TaskLock.updateTimeLeasedByName&Client");
   159              q.setParameter(1, Integer.valueOf(0));
   160              q.setParameter(2, task.getName());
   161              q.setParameter(3, task.getClientId());
   162              int result = q.executeUpdate();
   163              
   164              if(result == 1) {
   165                  return true;
   166              }
   167  
   168          } catch (Exception e) {
   169              log.warn("Error releasing lease.", e);
   170              return false;
   171          }
   172  
   173          return false;
   174  
   175      }
   176      
   177      
   178      /**
   179       * @inheritDoc
   180       */
   181      public TaskLock getTaskLockByName(String name) throws WebloggerException {
   182          // do lookup
                 /* 
    P/P           *  Method: TaskLock getTaskLockByName(String)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   183          Query q = strategy.getNamedQuery("TaskLock.getByName");
   184          q.setParameter(1, name);
   185          try {
   186              return (TaskLock)q.getSingleResult();
   187          } catch (NoResultException e) {
   188              return null;
   189          }
   190      }
   191  
   192      
   193      /**
   194       * @inheritDoc
   195       */
   196      public void saveTaskLock(TaskLock data) throws WebloggerException {
                 /* 
    P/P           *  Method: void saveTaskLock(TaskLock)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  */
   197          this.strategy.store(data);
   198      }
   199  
   200  }








SofCheck Inspector Build Version : 2.18479
JPAThreadManagerImpl.java 2009-Jan-02 14:25:24
JPAThreadManagerImpl.class 2009-Sep-04 03:12:32