Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>RequestCycle is a thread local singleton. If you're running a process in another thread that really means the RequestCycle singleton doesn't exist in your new thread.</p> <p>The following example is placed on <a href="https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-1.4/browse" rel="nofollow">https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-1.4/browse</a></p> <p>The idea is about holding the reference to the current RequestCycle, you cannot call RequestCycle.get() due to the thread local singleton doesn't exist in any other thread. This CustomRequestCycle implementation is ever waiting until the new thread notify its finishing. The counter of loops is just a protection to do not freeze the primary thread if the WaitingRunnable stops working/freezes.</p> <p><strong>RESULTS oF TESTS:</strong></p> <p>Check your logs for <strong>case 1</strong>, the separate thread is finishing very soon, <strong>RequestCycle doesn't wait for detaching</strong></p> <pre><code>http://localhost:8080/wicket-examples14/wait?millis=10 DEBUG - CustomRequestCycle - Waiting until notify: 0 INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage INFO - CustomRequestCycle - Notifier returned: Successfully finished </code></pre> <p>Check your logs for <strong>case 2</strong>, the separate thread is finishing in time, <strong>RequestCycle has to wait for detaching</strong> </p> <pre><code>http://localhost:8080/wicket-examples14/wait?millis=3000 DEBUG - CustomRequestCycle - Waiting until notify: 0 DEBUG - CustomRequestCycle - Waiting until notify: 1 DEBUG - CustomRequestCycle - Waiting until notify: 2 INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage INFO - CustomRequestCycle - Notifier returned: Successfully finished </code></pre> <p>Check your logs for <strong>case 3</strong>, the separate thread is finishing on time, <strong>RequestCycle is already detached</strong> </p> <pre><code>http://localhost:8080/wicket-examples14/wait?millis=10000 DEBUG - CustomRequestCycle - Waiting until notify: 0 DEBUG - CustomRequestCycle - Waiting until notify: 1 DEBUG - CustomRequestCycle - Waiting until notify: 2 DEBUG - CustomRequestCycle - Waiting until notify: 3 DEBUG - CustomRequestCycle - Waiting until notify: 4 DEBUG - CustomRequestCycle - Waiting until notify: 5 DEBUG - CustomRequestCycle - Waiting until notify: 6 DEBUG - CustomRequestCycle - Waiting until notify: 7 INFO - CustomRequestCycle - Notifier returned: null INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage </code></pre> <hr> <p><strong>SOURCES:</strong></p> <p><strong>WicketApplication</strong></p> <pre><code>@Override public RequestCycle newRequestCycle(Request request, Response response) { return new CustomRequestCycle(this, (WebRequest)request, (WebResponse)response); } </code></pre> <p><strong>CustomRequestCycle</strong></p> <pre><code>public class CustomRequestCycle extends WebRequestCycle implements INotifier&lt;String&gt; { private static final Logger log = LoggerFactory.getLogger(CustomRequestCycle.class); private long sleepTime = 1000L; private long maxLoops = 8; private boolean canDetach = true; private String notifierResult; public CustomRequestCycle(WicketApplication application, WebRequest request, Response response) { super(application, request, response); } public void notifyAny(String payload) { notifierResult = payload; canDetach = true; } @Override public void detach() { long counter = 0; while(!canDetach &amp;&amp; maxLoops &gt; counter) { log.debug("Waiting until notify: " + counter); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { // do nothing } counter++; } log.info("Notifier returned: " + notifierResult); super.detach(); } public static CustomRequestCycle get() { return (CustomRequestCycle)RequestCycle.get(); } /** * @return the canDetach */ public boolean isCanDetach() { return canDetach; } /** * @param canDetach the canDetach to set */ public void setCanDetach(boolean canDetach) { this.canDetach = canDetach; } } </code></pre> <p><strong>WaitingRunnableNotifier</strong></p> <pre><code>public class WaitingRunnableNotifier implements Runnable { private static final Logger log = LoggerFactory.getLogger(WaitingRunnableNotifier.class); private final long waitTime; private RequestCycle requestCycle; private INotifier&lt;String&gt; notifier; public WaitingRunnableNotifier(RequestCycle requestCycle, long waitTime, INotifier&lt;String&gt; notifier) { super(); this.notifier = notifier; this.requestCycle = requestCycle; this.waitTime = waitTime; } public void run() { String message = null; try { try { Thread.sleep(waitTime); } catch (InterruptedException e) { } log.info("Separate thread waiting finished " + requestCycle.getResponsePageClass().getCanonicalName()); message = "Successfully finished"; } catch (Exception e) { log.error("Exception during WaitingRunnableNotifier.run()", e); message = "Exception: " + e.getMessage(); } finally { notifier.notifyAny(message); clean(); } } /** * Clean object references */ private void clean() { requestCycle = null; notifier = null; } } </code></pre> <p><strong>ThreadWaitingPage</strong> is a page with parameter 'millis'. There you can invoke the another thread and wait unitl it is finished.</p> <pre><code>public class ThreadWaitingPage extends WebPage { private static final long serialVersionUID = 1L; private final long millis; public ThreadWaitingPage(final PageParameters parameters) { super(parameters); millis = parameters.getLong("millis"); add(new Label("millis", String.valueOf(millis))); } @Override protected void onInitialize() { super.onInitialize(); CustomRequestCycle requestCycle = CustomRequestCycle.get(); requestCycle.setCanDetach(false); new Thread(new WaitingRunnableNotifier(requestCycle, millis, requestCycle)).start(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload