<br><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">Do you have a sense of the differences in response time between<br>
cancel()ing the request without this extra thread vs/ with it?  Seems<br>
like if the code is able to poll often enough<br></blockquote><div><br>Our experience has shown that there are cases where the cancellation cannot occur as expected. When Mondrian is issuing a long running SQL query, there was no way to make the MDX request timeout correctly. As we want to avoid doing a hard kill of threads (we&#39;d rather have the JDBC resources freed properly in the background so as not to hose the RDBMS and whatever other symptoms), we needed to split the user thread from the execution thread.<br>

<br>Julian mentioned Execution.peek(). He should have mentioned Locus.peek() instead. Using this static accessor, your UDF will be capable of accessing the Execution instance of your particular thread by doing &quot;Locus.peek().execution&quot;. Let&#39;s work together to figure out which information the Execution state should contain.<br>

<br>Luc<br> </div><br><div class="gmail_quote">On Wed, Jul 13, 2011 at 6:35 PM, Julian Hyde <span dir="ltr">&lt;<a href="mailto:jhyde@pentaho.com">jhyde@pentaho.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Take a look at Execution.peek(). I want to reduce the use of thread-locals<br>
in mondrian because they make it more difficult to have a parallel execution<br>
model. As much state as possible should be stored in Execution. However, I<br>
know I can&#39;t eradicate thread-locals overnight.<br>
<br>
Execution.peek() will allow you to retrieve the current Execution object.<br>
Under the covers it uses -- you guessed it -- a thread-local. (So you don&#39;t<br>
have to.)<br>
<br>
Use Execution.peek() when your thread starts work, and store the Execution<br>
object in its local state.<br>
<br>
Execution isn&#39;t a supported API yet, but we can evolve it into one once<br>
we&#39;ve proved the approach is viable.<br>
<br>
Julian<br>
<br>
<br>
&gt; -----Original Message-----<br>
&gt; From: <a href="mailto:mondrian-bounces@pentaho.org">mondrian-bounces@pentaho.org</a><br>
&gt; [mailto:<a href="mailto:mondrian-bounces@pentaho.org">mondrian-bounces@pentaho.org</a>] On Behalf Of Joe Barnett<br>
&gt; Sent: Wednesday, July 13, 2011 3:25 PM<br>
&gt; To: Mondrian developer mailing list<br>
&gt; Subject: Re: [Mondrian] Mondrian Query Timeout<br>
<div><div></div><div class="h5">&gt;<br>
&gt; One potential concern I have with this is that we have a UDF that<br>
&gt; essentially relies upon ThreadLocals that are set up by our<br>
&gt; application to control routing to the appropriate database.  Actually,<br>
&gt; the DataSources we pass to mondrian rely on those ThreadLocals as<br>
&gt; well, so not actually UDF specific.  It sounds like this approach<br>
&gt; would have mondrian run in a separate thread context, and hence not<br>
&gt; have the appropriate ThreadLocal values set.<br>
&gt;<br>
&gt; Are you planning on adding any hooks to the thread fork where we might<br>
&gt; be able to set up the thread appropriately?  We&#39;d also probably have<br>
&gt; to adjust some things (connection pools, etc) to expect an additional<br>
&gt; thread per thread-that-calls-into-mondrian, but would need to study<br>
&gt; the exact execution patterns a little more closely to see if that&#39;s<br>
&gt; really necessary.<br>
&gt;<br>
&gt; Do you have a sense of the differences in response time between<br>
&gt; cancel()ing the request without this extra thread vs/ with it?  Seems<br>
&gt; like if the code is able to poll often enough (and<br>
&gt; interrupt()/cancel() any underlying IO), the difference should be<br>
&gt; negligible enough?  But not sure exactly where all the<br>
&gt; cancel-checking-hooks are.<br>
&gt;<br>
&gt; Other thoughts?<br>
&gt;<br>
&gt; -Joe<br>
&gt;<br>
&gt; On Tue, Jul 12, 2011 at 7:35 AM, Luc Boudreau<br>
&gt; &lt;<a href="mailto:lucboudreau@gmail.com">lucboudreau@gmail.com</a>&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt; Good. That&#39;s exactly what I had in mind.<br>
&gt; &gt;<br>
&gt; &gt; As for b), we are using backport-util-concurrent so I think<br>
&gt; we&#39;re good.I&#39;ll<br>
&gt; &gt; make sure to test thoroughly.<br>
&gt; &gt;<br>
&gt; &gt; Luc<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; On Mon, Jul 11, 2011 at 6:21 PM, Julian Hyde<br>
&gt; &lt;<a href="mailto:jhyde@pentaho.com">jhyde@pentaho.com</a>&gt; wrote:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; However we solve this, we need a data structure that<br>
&gt; records all SQL<br>
&gt; &gt;&gt; statements that are running in the service of a particular<br>
&gt; MDX statement.<br>
&gt; &gt;&gt; The Execution class that I added on Friday (see<br>
&gt; &gt;&gt; <a href="http://p4web.eigenbase.org/@md=d&amp;c=6PU@/14436?ac=10" target="_blank">http://p4web.eigenbase.org/@md=d&amp;c=6PU@/14436?ac=10</a> ) is<br>
&gt; perfect for this.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I couldn&#39;t tell whether you were suggesting this, but just<br>
&gt; in case, let me<br>
&gt; &gt;&gt; state for the record: I think that killing Java threads is<br>
&gt; a bad idea. It is<br>
&gt; &gt;&gt; very likely to make a mess. I think that Java code under<br>
&gt; mondrian&#39;s control<br>
&gt; &gt;&gt; should continue to poll the &#39;canceled&#39; flag. (Which on<br>
&gt; Friday moved from<br>
&gt; &gt;&gt; Query to Execution.)<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; For SQL statements, mondrian should definitely call<br>
&gt; cancel. If the JDBC<br>
&gt; &gt;&gt; driver of the database concerned is well-implemented, it<br>
&gt; will do something<br>
&gt; &gt;&gt; sensible with the cancel request. (Probably three things:<br>
&gt; cancel the<br>
&gt; &gt;&gt; synchronous call fairly quicky, throw a SQLException<br>
&gt; indicating that the<br>
&gt; &gt;&gt; statement is canceled, and send a message to the deeper<br>
&gt; parts of the<br>
&gt; &gt;&gt; infrastructure to cancel asynchronous processing, slower but more<br>
&gt; &gt;&gt; exhaustively.)<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Since Mondrian is itself an JDBC server (by virtue of<br>
&gt; olap4j being an<br>
&gt; &gt;&gt; extension to JDBC), we should do something similar. It&#39;s<br>
&gt; worth asking: what<br>
&gt; &gt;&gt; MondrianOlap4jStatement.executeOlapQuery() should do when<br>
&gt; canceled? I expect<br>
&gt; &gt;&gt; that Execute.cancel will be polled every ~millisecond, so<br>
&gt; cancel the<br>
&gt; &gt;&gt; statement should come back fairly quickly. We could make<br>
&gt; it come back<br>
&gt; &gt;&gt; quicker still if executeOlapQuery were making a call to<br>
&gt; another thread. Then<br>
&gt; &gt;&gt; we could interrupt that call without damaging either of<br>
&gt; the threads.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Let me be clear that this is a &quot;nice to have&quot;. And there are some<br>
&gt; &gt;&gt; implementation details I haven&#39;t solved:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; (a) I am speculating that there is an &#39;cancelable future&#39;<br>
&gt; in JDK 1.6<br>
&gt; &gt;&gt; off-the-shelf. I mean: create a Future, have another<br>
&gt; thread (from an<br>
&gt; &gt;&gt; ExecutionService presumably) do the work, and allow any<br>
&gt; 3rd thread to cancel<br>
&gt; &gt;&gt; that call. Is this available in the JDK?<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; (b) If the calls you need are not available in JDK 1.4 or<br>
&gt; JDK 1.5, it&#39;s OK<br>
&gt; &gt;&gt; if they have inferior behavior. But it still needs to<br>
&gt; build &amp; run in those<br>
&gt; &gt;&gt; JDKs.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; (c) MondrianOlap4jStatement.executeOlapQuery is not<br>
&gt; necessarily the right<br>
&gt; &gt;&gt; place in the architecture to make the asynchronous<br>
&gt; &#39;slice&#39;. Find the ideal<br>
&gt; &gt;&gt; place, maybe a little ways below it. But note that<br>
&gt; Locus.peek() etc. uses a<br>
&gt; &gt;&gt; thread-local.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Julian<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ________________________________<br>
&gt; &gt;&gt; From: Luc Boudreau [mailto:<a href="mailto:lucboudreau@gmail.com">lucboudreau@gmail.com</a>]<br>
&gt; &gt;&gt; Sent: Monday, July 11, 2011 8:57 AM<br>
&gt; &gt;&gt; To: Julian Hyde<br>
&gt; &gt;&gt; Cc: Mondrian developer mailing list<br>
&gt; &gt;&gt; Subject: Mondrian Query Timeout<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Julian,<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Following your commit on the statements refactoring, I<br>
&gt; have started to<br>
&gt; &gt;&gt; think about how we would now enforce a proper query<br>
&gt; timeout. (MONDRIAN-415).<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; What I had in mind is a simple system where, when creating<br>
&gt; RolapResult<br>
&gt; &gt;&gt; objects (in RolapConnection.execute()) we fork the<br>
&gt; execution to a second<br>
&gt; &gt;&gt; thread (let’s call it the execution thread). The first<br>
&gt; thread (let’s call it<br>
&gt; &gt;&gt; the user thread) will wait a predetermined amount of time<br>
&gt; (the actual<br>
&gt; &gt;&gt; timeout) and if the execution thread has not completed,<br>
&gt; the user thread will<br>
&gt; &gt;&gt; perform the following.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Stop all SQL statements currently associated to this Execution.<br>
&gt; &gt;&gt; Do house cleaning.<br>
&gt; &gt;&gt; Bake a cake. (optional)<br>
&gt; &gt;&gt; Throw back a timeout exception.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; This has several advantages. First off, we could remove<br>
&gt; all checks for<br>
&gt; &gt;&gt; query timeout in the evaluator and centralize everything<br>
&gt; in a single place.<br>
&gt; &gt;&gt; Second, as it stands now, there is no way to do a “hard<br>
&gt; stop” of any SQL<br>
&gt; &gt;&gt; statements running for a given Execution as we sit in the<br>
&gt; same thread. As<br>
&gt; &gt;&gt; long as the SQL Statement has not returned, we have no way<br>
&gt; to check for a<br>
&gt; &gt;&gt; timeout. As of now, the best we can do is to set an<br>
&gt; arbitrary JDBC timeout,<br>
&gt; &gt;&gt; but since there is no telling how many SQL statements will<br>
&gt; be issued, nor<br>
&gt; &gt;&gt; their priority, we cannot determine the proper JDBC<br>
&gt; timeout value to apply.<br>
&gt; &gt;&gt; By having the user thread overview the execution process,<br>
&gt; it becomes much<br>
&gt; &gt;&gt; simpler to manage and cleanup all the resources used by a<br>
&gt; query execution.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Should I try this approach and submit a first POC?<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; Mondrian mailing list<br>
&gt; &gt; <a href="mailto:Mondrian@pentaho.org">Mondrian@pentaho.org</a><br>
&gt; &gt; <a href="http://lists.pentaho.org/mailman/listinfo/mondrian" target="_blank">http://lists.pentaho.org/mailman/listinfo/mondrian</a><br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; _______________________________________________<br>
&gt; Mondrian mailing list<br>
&gt; <a href="mailto:Mondrian@pentaho.org">Mondrian@pentaho.org</a><br>
&gt; <a href="http://lists.pentaho.org/mailman/listinfo/mondrian" target="_blank">http://lists.pentaho.org/mailman/listinfo/mondrian</a><br>
&gt;<br>
<br>
_______________________________________________<br>
Mondrian mailing list<br>
<a href="mailto:Mondrian@pentaho.org">Mondrian@pentaho.org</a><br>
<a href="http://lists.pentaho.org/mailman/listinfo/mondrian" target="_blank">http://lists.pentaho.org/mailman/listinfo/mondrian</a><br>
</div></div></blockquote></div><br>