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 |