make locks expire
git-svn-id: http://google-refine.googlecode.com/svn/trunk@1014 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
2237ec2335
commit
f690c55fab
5
.gitignore
vendored
5
.gitignore
vendored
@ -9,4 +9,7 @@ appengine/classes/
|
|||||||
tools/
|
tools/
|
||||||
extensions/sample-extension/module/MOD-INF/classes/
|
extensions/sample-extension/module/MOD-INF/classes/
|
||||||
extensions/jython/module/MOD-INF/classes/
|
extensions/jython/module/MOD-INF/classes/
|
||||||
extensions/jython/module/MOD-INF/lib/cachedir/
|
extensions/jython/module/MOD-INF/lib/cachedir/
|
||||||
|
broker/appengine/module/MOD-INF/classes/
|
||||||
|
broker/core/module/MOD-INF/classes/
|
||||||
|
broker/local/module/MOD-INF/classes/
|
||||||
|
7
broker/appengine/WEB-INF/cron.xml
Normal file
7
broker/appengine/WEB-INF/cron.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<cronentries>
|
||||||
|
<cron>
|
||||||
|
<url>/expire_locks</url>
|
||||||
|
<schedule>every 5 seconds synchronized</schedule>
|
||||||
|
</cron>
|
||||||
|
</cronentries>
|
@ -1,10 +1,6 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
<!DOCTYPE web-app
|
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
|
||||||
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
|
|
||||||
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
|
|
||||||
|
|
||||||
<web-app>
|
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>Butterfly</servlet-name>
|
<servlet-name>Butterfly</servlet-name>
|
||||||
@ -16,5 +12,14 @@
|
|||||||
<servlet-name>Butterfly</servlet-name>
|
<servlet-name>Butterfly</servlet-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<url-pattern>/expire_locks</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
|
||||||
</web-app>
|
</web-app>
|
||||||
|
@ -4,6 +4,7 @@ import java.io.Writer;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.jdo.Extent;
|
||||||
import javax.jdo.JDOHelper;
|
import javax.jdo.JDOHelper;
|
||||||
import javax.jdo.PersistenceManager;
|
import javax.jdo.PersistenceManager;
|
||||||
import javax.jdo.PersistenceManagerFactory;
|
import javax.jdo.PersistenceManagerFactory;
|
||||||
@ -53,6 +54,39 @@ public class AppEngineGridworksBroker extends GridworksBroker {
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected void expireLocks(HttpServletResponse response) throws Exception {
|
||||||
|
|
||||||
|
PersistenceManager pm = pmfInstance.getPersistenceManager();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Extent<Lock> extent = pm.getExtent(Lock.class, false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (Lock lock : extent) {
|
||||||
|
if (lock.timestamp + LOCK_DURATION < System.currentTimeMillis()) {
|
||||||
|
Transaction tx = pm.currentTransaction();
|
||||||
|
try {
|
||||||
|
tx.begin();
|
||||||
|
pm.deletePersistent(lock);
|
||||||
|
tx.commit();
|
||||||
|
} finally {
|
||||||
|
if (tx.isActive()) {
|
||||||
|
tx.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
extent.closeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
respond(response, OK);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
pm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void getLock(HttpServletResponse response, String pid) throws Exception {
|
protected void getLock(HttpServletResponse response, String pid) throws Exception {
|
||||||
PersistenceManager pm = pmfInstance.getPersistenceManager();
|
PersistenceManager pm = pmfInstance.getPersistenceManager();
|
||||||
|
|
||||||
@ -295,6 +329,7 @@ public class AppEngineGridworksBroker extends GridworksBroker {
|
|||||||
o.put("lock_id", lock.id);
|
o.put("lock_id", lock.id);
|
||||||
o.put("project_id", lock.pid);
|
o.put("project_id", lock.pid);
|
||||||
o.put("user_id", lock.uid);
|
o.put("user_id", lock.uid);
|
||||||
|
o.put("timestamp", lock.timestamp);
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -312,10 +347,14 @@ public class AppEngineGridworksBroker extends GridworksBroker {
|
|||||||
@Persistent
|
@Persistent
|
||||||
String uid;
|
String uid;
|
||||||
|
|
||||||
|
@Persistent
|
||||||
|
long timestamp;
|
||||||
|
|
||||||
Lock(String id, String pid, String uid) {
|
Lock(String id, String pid, String uid) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.pid = pid;
|
this.pid = pid;
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
|
this.timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,9 @@ public abstract class GridworksBroker extends ButterflyModuleImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public final long LOCK_DURATION = 60 * 1000; // 1 minute
|
||||||
|
static public final long LOCK_EXPIRATION_CHECK_DELAY = 5 * 1000; // 5 seconds
|
||||||
|
|
||||||
protected HttpClient httpclient;
|
protected HttpClient httpclient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -98,6 +101,8 @@ public abstract class GridworksBroker extends ButterflyModuleImpl {
|
|||||||
|
|
||||||
if ("get_lock".equals(path)) {
|
if ("get_lock".equals(path)) {
|
||||||
getLock(response, pid);
|
getLock(response, pid);
|
||||||
|
} else if ("expire_locks".equals(path)) {
|
||||||
|
expireLocks(response);
|
||||||
} else if ("obtain_lock".equals(path)) {
|
} else if ("obtain_lock".equals(path)) {
|
||||||
obtainLock(response, pid, uid);
|
obtainLock(response, pid, uid);
|
||||||
} else if ("release_lock".equals(path)) {
|
} else if ("release_lock".equals(path)) {
|
||||||
@ -128,6 +133,8 @@ public abstract class GridworksBroker extends ButterflyModuleImpl {
|
|||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
protected abstract HttpClient getHttpClient();
|
protected abstract HttpClient getHttpClient();
|
||||||
|
|
||||||
|
protected abstract void expireLocks(HttpServletResponse response) throws Exception;
|
||||||
|
|
||||||
protected abstract void getLock(HttpServletResponse response, String pid) throws Exception;
|
protected abstract void getLock(HttpServletResponse response, String pid) throws Exception;
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import java.io.File;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@ -36,12 +38,17 @@ public class LocalGridworksBroker extends GridworksBroker {
|
|||||||
PrimaryIndex<String,Project> projectById;
|
PrimaryIndex<String,Project> projectById;
|
||||||
PrimaryIndex<String,Lock> lockByProject;
|
PrimaryIndex<String,Lock> lockByProject;
|
||||||
|
|
||||||
protected HttpClient httpclient;
|
Timer timer;
|
||||||
|
LockExpirer expirer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(ServletConfig config) throws Exception {
|
public void init(ServletConfig config) throws Exception {
|
||||||
super.init(config);
|
super.init(config);
|
||||||
|
|
||||||
|
timer = new Timer();
|
||||||
|
expirer = new LockExpirer();
|
||||||
|
timer.schedule(expirer, LOCK_EXPIRATION_CHECK_DELAY, LOCK_EXPIRATION_CHECK_DELAY);
|
||||||
|
|
||||||
File dataPath = new File("data"); // FIXME: data should be configurable;
|
File dataPath = new File("data"); // FIXME: data should be configurable;
|
||||||
|
|
||||||
EnvironmentConfig envConfig = new EnvironmentConfig();
|
EnvironmentConfig envConfig = new EnvironmentConfig();
|
||||||
@ -77,6 +84,20 @@ public class LocalGridworksBroker extends GridworksBroker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LockExpirer extends TimerTask {
|
||||||
|
public void run() {
|
||||||
|
for (Lock lock : lockByProject.entities()) {
|
||||||
|
if (lock.timestamp + LOCK_DURATION < System.currentTimeMillis()) {
|
||||||
|
try {
|
||||||
|
releaseLock(null, lock.pid, lock.uid, lock.id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Exception while expiring lock for project '" + lock.pid + "'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
protected HttpClient getHttpClient() {
|
protected HttpClient getHttpClient() {
|
||||||
@ -85,6 +106,11 @@ public class LocalGridworksBroker extends GridworksBroker {
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected void expireLocks(HttpServletResponse response) throws Exception {
|
||||||
|
expirer.run();
|
||||||
|
respond(response, OK);
|
||||||
|
}
|
||||||
|
|
||||||
protected void getLock(HttpServletResponse response, String pid) throws Exception {
|
protected void getLock(HttpServletResponse response, String pid) throws Exception {
|
||||||
respond(response, lockToJSON(getLock(pid)));
|
respond(response, lockToJSON(getLock(pid)));
|
||||||
}
|
}
|
||||||
@ -135,7 +161,9 @@ public class LocalGridworksBroker extends GridworksBroker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
respond(response, OK);
|
if (response != null) { // this because the expiration thread can call this method without a real response
|
||||||
|
respond(response, OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------
|
||||||
@ -283,6 +311,7 @@ public class LocalGridworksBroker extends GridworksBroker {
|
|||||||
o.put("lock_id", lock.id);
|
o.put("lock_id", lock.id);
|
||||||
o.put("project_id", lock.pid);
|
o.put("project_id", lock.pid);
|
||||||
o.put("user_id", lock.uid);
|
o.put("user_id", lock.uid);
|
||||||
|
o.put("timestamp", lock.timestamp);
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -297,10 +326,13 @@ public class LocalGridworksBroker extends GridworksBroker {
|
|||||||
|
|
||||||
String uid;
|
String uid;
|
||||||
|
|
||||||
|
long timestamp;
|
||||||
|
|
||||||
Lock(String id, String pid, String uid) {
|
Lock(String id, String pid, String uid) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.pid = pid;
|
this.pid = pid;
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
|
this.timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
Loading…
Reference in New Issue
Block a user