* Implement app.invokeAsync() using public FutureResult interface.
This commit is contained in:
parent
a0ea3b31de
commit
7f58c102bf
2 changed files with 146 additions and 73 deletions
59
src/helma/framework/FutureResult.java
Normal file
59
src/helma/framework/FutureResult.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2006 Hannes Wallnoefer <hannes@helma.at>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package helma.framework;
|
||||
|
||||
/**
|
||||
* A handle for an asynchronous request execution. This allows to wait for
|
||||
* request termination, get the result or the exception of the execution.
|
||||
*/
|
||||
public interface FutureResult {
|
||||
/**
|
||||
* Get the result of the execution. If the execution is still active,
|
||||
* or if the invocation threw an exception, this method immediately returns null.
|
||||
* @return the result, or null
|
||||
*/
|
||||
Object getResult();
|
||||
|
||||
/**
|
||||
* Get the exception of the execution, if one was thrown. If the execution
|
||||
* is still active, or if no exception was thrown, this method immediately returns null.
|
||||
* @return the exception, or null
|
||||
*/
|
||||
Exception getException();
|
||||
|
||||
/**
|
||||
* Returns true if the execution is still active, and false if not.
|
||||
* @return true if the execution is still active
|
||||
*/
|
||||
boolean getRunning();
|
||||
|
||||
/**
|
||||
* Wait for execution to terminat, returning the execution result, if one is available.
|
||||
* @return the execution result, or null
|
||||
* @throws InterruptedException if we were interrupted by some other thread
|
||||
*/
|
||||
Object waitForResult() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Wait for a specific ammount of thime for the execution to terminate, returning
|
||||
* the execution result, if one is available.
|
||||
* @param timeout the number of milliseconds to wait
|
||||
* @return the execution result, or null
|
||||
* @throws InterruptedException if we were interrupted by some other thread
|
||||
*/
|
||||
Object waitForResult(long timeout) throws InterruptedException;
|
||||
}
|
|
@ -22,6 +22,7 @@ import helma.util.CronJob;
|
|||
import helma.util.SystemMap;
|
||||
import helma.util.WrappedMap;
|
||||
import helma.framework.repository.*;
|
||||
import helma.framework.FutureResult;
|
||||
import helma.main.Server;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -33,7 +34,8 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application bean that provides a handle to the scripting environment to
|
||||
* application specific functionality.
|
||||
*/
|
||||
public class ApplicationBean implements Serializable {
|
||||
Application app;
|
||||
|
@ -682,11 +684,11 @@ public class ApplicationBean implements Serializable {
|
|||
* this long, we will try to interrupt the invocation
|
||||
* @return an object with the properties described above
|
||||
*/
|
||||
public Object invokeAsync(Object thisObject,
|
||||
public FutureResult invokeAsync(Object thisObject,
|
||||
final Object function,
|
||||
final Object[] args) {
|
||||
// default timeout of 15 minutes
|
||||
return invokeAsync(thisObject, function, args, 60000L * 15);
|
||||
return new AsyncInvoker(thisObject, function, args, 60000L * 15);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -712,16 +714,38 @@ public class ApplicationBean implements Serializable {
|
|||
* this long, we will try to interrupt the invocation
|
||||
* @return an object with the properties described above
|
||||
*/
|
||||
public Object invokeAsync(final Object thisObject,
|
||||
final Object function,
|
||||
final Object[] args,
|
||||
final long timeout) {
|
||||
Thread thread = new Thread() {
|
||||
public FutureResult invokeAsync(Object thisObject, Object function,
|
||||
Object[] args, long timeout) {
|
||||
return new AsyncInvoker(thisObject, function, args, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string presentation of this AppBean
|
||||
* @return string description of this app bean object
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Application " + app.getName() + "]";
|
||||
}
|
||||
|
||||
class AsyncInvoker extends Thread implements FutureResult {
|
||||
|
||||
private Object thisObject;
|
||||
private Object function;
|
||||
private Object[] args;
|
||||
private long timeout;
|
||||
|
||||
private Object result;
|
||||
private Exception exception;
|
||||
private boolean running = true;
|
||||
|
||||
private AsyncInvoker(Object thisObj, Object func, Object[] args, long timeout) {
|
||||
thisObject = thisObj;
|
||||
function = func;
|
||||
this.args = args;
|
||||
this.timeout = timeout;
|
||||
start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
RequestEvaluator reval = null;
|
||||
try {
|
||||
|
@ -779,16 +803,6 @@ public class ApplicationBean implements Serializable {
|
|||
.append(", result: ").append(result).append(", exception: ")
|
||||
.append(exception).append("}").toString();
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
return thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string presentation of this AppBean
|
||||
* @return string description of this app bean object
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Application " + app.getName() + "]";
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue