* Implement app.invokeAsync() using public FutureResult interface.

This commit is contained in:
hns 2007-04-02 15:51:02 +00:00
parent a0ea3b31de
commit 7f58c102bf
2 changed files with 146 additions and 73 deletions

View 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;
}

View file

@ -22,6 +22,7 @@ import helma.util.CronJob;
import helma.util.SystemMap; import helma.util.SystemMap;
import helma.util.WrappedMap; import helma.util.WrappedMap;
import helma.framework.repository.*; import helma.framework.repository.*;
import helma.framework.FutureResult;
import helma.main.Server; import helma.main.Server;
import java.io.File; import java.io.File;
@ -33,7 +34,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 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 { public class ApplicationBean implements Serializable {
Application app; Application app;
@ -682,11 +684,11 @@ public class ApplicationBean implements Serializable {
* this long, we will try to interrupt the invocation * this long, we will try to interrupt the invocation
* @return an object with the properties described above * @return an object with the properties described above
*/ */
public Object invokeAsync(Object thisObject, public FutureResult invokeAsync(Object thisObject,
final Object function, final Object function,
final Object[] args) { final Object[] args) {
// default timeout of 15 minutes // 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 * this long, we will try to interrupt the invocation
* @return an object with the properties described above * @return an object with the properties described above
*/ */
public Object invokeAsync(final Object thisObject, public FutureResult invokeAsync(Object thisObject, Object function,
final Object function, Object[] args, long timeout) {
final Object[] args, return new AsyncInvoker(thisObject, function, args, timeout);
final long timeout) { }
Thread thread = new Thread() {
/**
* 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 Object result;
private Exception exception; private Exception exception;
private boolean running = true; 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() { public void run() {
RequestEvaluator reval = null; RequestEvaluator reval = null;
try { try {
@ -779,16 +803,6 @@ public class ApplicationBean implements Serializable {
.append(", result: ").append(result).append(", exception: ") .append(", result: ").append(result).append(", exception: ")
.append(exception).append("}").toString(); .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() + "]";
} }
} }