On 10/9/2017 12:56 PM, Christoph Nenning wrote: > I'd rather have just a very thin wrapper around servlet api, like so: > - actions might be declared async, this causes struts to call > request.startAsync() > - applications using that must use their own threads to do work (as with > servlet api) > - it should still be possible to use all struts results > - we need some mechanism for the action to trigger result execution and > cleanup of async context (result may run in application managed thread as > well) > > > This would mean there is not too much and not too complicated code in > struts. Applications which would like to use servlet api async context > could do so and still use struts concepts like interceptors, results or > ognl. It is up to the application to gain something of async, as it is > with servlet api.
Yes I see. However, it seems execAndWait interceptor already can do a similar work. I think the lack of support is at result side and upload side. I thought If I define three phases: upload, action and result, and define S as short time and L as long time (spends process), then we have 8 states from SSS to LLL. For example: LLL: a lot of users want to upload video and download converted one SSL: a lot of users want to download specific files (download server) SLS: seems execAndWait interceptor can handle this one I even thought I can have 16 states by defining if result is dependent to action or not :) Moreover, maybe this is not as simple as it appears too, I guess. Struts is a filter and user may use other filters before or after. To satisfy servlet3, we should immediately release current thread back to container when async action reached, so, what we should pass as result to back interceptors and filters now? maybe null result and save original result somewhere waiting for action back but we lose thread local attached data :( and currently I'm not sure what happens when we execute a result in separate empty thread! If @dev agree I have an idea. For first step, what do you think to level-up it to filter level (as it already is)? When I was playing I had developed a modified filter below and saw it works! (except a few special cases like when user has request scope spring bean). User can put async actions in a specific namespace then map those to this filter instead setting async-support to true. Below is some simple codes of this filter (all params can be changed to get by a filter-param): public class StrutsExecuteFilter { public final int REQUEST_TIMEOUT = 240000; private ExecutorService exe; @Override public void init(FilterConfig filterConfig) throws ServletException { if(async-supported && async){ int size = 41; exe = Executors.newFixedThreadPool( size, new ThreadFactory() { public Thread newThread(Runnable r) { return new Thread(r, "Struts Async Processor"); } } ); } //Strut's current init codes } @Override public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException { //Strut's current codes if (mapping == null || recursionCounter > 1) { boolean handled = execute.executeStaticResourceRequest(request, response); if (!handled) { chain.doFilter(request, response); } } else { //I ADDED THESE final AsyncContext context = req.startAsync(); context.setTimeout(REQUEST_TIMEOUT); context.addListener(new AsyncListener() { public void onComplete(AsyncEvent asyncEvent) throws IOException { } public void onTimeout(AsyncEvent asyncEvent) throws IOException { context .getResponse() .getWriter().write("Request Timeout"); } public void onError(AsyncEvent asyncEvent) throws IOException { context .getResponse() .getWriter().write("Processing Error"); } public void onStartAsync(AsyncEvent asyncEvent) throws IOException { } }); exe.execute(new ContextExecution(context, mapping)); } } @Override public void destroy() { exe.shutdown(); //Strut's current destroy } class ContextExecution implements Runnable { final AsyncContext context; ActionMapping mapping; public ContextExecution(AsyncContext context, ActionMapping mapping) { this.context = context; this.mapping=mapping; } public void run() { try { execute.executeAction((HttpServletRequest) context.getRequest(), (HttpServletResponse) context.getResponse(), mapping); context.complete(); } catch (Exception e) { e.printStackTrace(); } } } } :) I love it Sincerely Yours, Yasser. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@struts.apache.org For additional commands, e-mail: dev-h...@struts.apache.org