mirror of
https://github.com/apache/struts.git
synced 2026-08-31 19:35:40 +00:00
WW-4874 Refactors technology name, servlet3, to asset name, async
This commit is contained in:
committed by
Yasser Zamani
parent
1c0976a869
commit
eaed709f1d
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.struts2.async;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* A {@link Callable} with a timeout value and an {@link Executor}.
|
||||
*
|
||||
* @since 2.5.14
|
||||
*/
|
||||
public class AsyncAction implements Callable {
|
||||
private Callable callable;
|
||||
private Long timeout;
|
||||
private Executor executor;
|
||||
|
||||
public AsyncAction(Callable callable) {
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
public AsyncAction(long timeout, Callable callable) {
|
||||
this(callable);
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public AsyncAction(Executor executor, Callable callable) {
|
||||
this(callable);
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public AsyncAction(long timeout, Executor executor, Callable callable) {
|
||||
this(timeout, callable);
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public Long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return callable.call();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.struts2.async;
|
||||
|
||||
import com.opensymphony.xwork2.AsyncManager;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Implements {@link AsyncManager} to add support for invoke async actions via Servlet 3's API.
|
||||
*
|
||||
* @since 2.5.14
|
||||
*/
|
||||
public class DefaultAsyncManager implements AsyncManager, AsyncListener {
|
||||
private static final Logger LOG = LogManager.getLogger(DefaultAsyncManager.class);
|
||||
private static final AtomicInteger threadCount = new AtomicInteger(0);
|
||||
|
||||
private AsyncContext asyncContext;
|
||||
private boolean asyncActionStarted;
|
||||
private Boolean asyncCompleted;
|
||||
private Object asyncActionResult;
|
||||
|
||||
@Override
|
||||
public void invokeAsyncAction(final Callable asyncAction) {
|
||||
if (asyncActionStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long timeout = null;
|
||||
Executor executor = null;
|
||||
if (asyncAction instanceof AsyncAction) {
|
||||
AsyncAction customAsyncAction = (AsyncAction) asyncAction;
|
||||
timeout = customAsyncAction.getTimeout();
|
||||
executor = customAsyncAction.getExecutor();
|
||||
}
|
||||
|
||||
HttpServletRequest req = ServletActionContext.getRequest();
|
||||
asyncActionResult = null;
|
||||
asyncCompleted = false;
|
||||
|
||||
if (asyncContext == null || !req.isAsyncStarted()) {
|
||||
asyncContext = req.startAsync(req, ServletActionContext.getResponse());
|
||||
asyncContext.addListener(this);
|
||||
if (timeout != null) {
|
||||
asyncContext.setTimeout(timeout);
|
||||
}
|
||||
}
|
||||
asyncActionStarted = true;
|
||||
LOG.debug("Async processing started for " + asyncContext);
|
||||
|
||||
final Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setAsyncActionResultAndDispatch(asyncAction.call());
|
||||
} catch (Throwable e) {
|
||||
setAsyncActionResultAndDispatch(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (executor != null) {
|
||||
executor.execute(task);
|
||||
} else {
|
||||
final Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
task.run();
|
||||
} finally {
|
||||
threadCount.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}, this.getClass().getSimpleName() + "-" + threadCount.incrementAndGet());
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void setAsyncActionResultAndDispatch(Object asyncActionResult) {
|
||||
this.asyncActionResult = asyncActionResult;
|
||||
|
||||
String log = "Async result [" + asyncActionResult + "] of " + asyncContext;
|
||||
if (asyncCompleted) {
|
||||
LOG.error(log + " - could not complete result executing due to timeout or network error");
|
||||
} else {
|
||||
LOG.debug(log + " - dispatching request to execute result in container");
|
||||
asyncContext.dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAsyncActionResult() {
|
||||
return asyncActionResult != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAsyncActionResult() {
|
||||
return asyncActionResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(AsyncEvent asyncEvent) throws IOException {
|
||||
asyncContext = null;
|
||||
asyncCompleted = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout(AsyncEvent asyncEvent) throws IOException {
|
||||
LOG.debug("Processing timeout for " + asyncEvent.getAsyncContext());
|
||||
setAsyncActionResultAndDispatch("timeout");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(AsyncEvent asyncEvent) throws IOException {
|
||||
Throwable e = asyncEvent.getThrowable();
|
||||
LOG.error("Processing error for " + asyncEvent.getAsyncContext(), e);
|
||||
setAsyncActionResultAndDispatch(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<bean type="com.opensymphony.xwork2.AsyncManager" name="default"
|
||||
class="org.apache.struts2.async.DefaultAsyncManager" scope="prototype" />
|
||||
</struts>
|
||||
Reference in New Issue
Block a user