This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: runnable closure limitation


Thanks for the explanation, that helps a lot. Your understanding of 
executors is correct. A common use case is a ScheduledThreadPoolExecutor, 
which executes a runnable at a fixed rate. The more insidious case is 
passing a runnable into a library which may be using thread pools internally.
(these situations are subtle because most executions will run in the same
thread, so things will appear to work correctly most of the time).

So for clarity, I think it's worthwhile to call these something 
other than closures. The conventional definition of closure 
calls for fixed correspondence between the closure and its 
environment. In this case, the connection is dynamic, so different 
terminology would be helpful to make the distinction clear.

The solution you suggested is close to what I'm doing now -- thank you
for confirming that approach.


 > > At one time, Kawa's implementation of runnable closures included
 > > an explicit reference to its environment. In the current
 > > implementation, it relies on the affinity between threads and
 > > environments to associate the runnable with the environment.
 > > This is fine for one-shot runnables, but it's a problem if the
 > > runnable is executed repeatedly by, say, a ThreadPoolExecutor,
 > > where the environment can change from one execution to the next
 > > (but then it's hardly a closure). I don't want to call this a bug
 > > since taking the environment ref out of RunnableClosure was
 > > clearly intentional (but why?), and I may have missed something.
 > >
 > > If this is the intended behavior of runnable, the documentation
 > > should make this limitation clear. Unfortunately it's not a
 > > fail-fast scenario, as things may appear to work properly for
 > > a long time if the executor uses the same task thread most of the
 > > time (which is often the case).
 > 
 > The main motivation, according to the ChangeLog was "so inheritance/fluids
 > works even for threads not created using 'future'/RunnableClosure."
 > This also, I think makes things simpler and more consistent:
 > We have the "current" Environment (and other properties),
 > where current is relative to the current thread.  There is
 > a bunch of places where we use some variant of a ThreadLocal
 > to get at these variables.
 > 
 > It does look like this conversion is incomplete: The standard
 > ports should should probably also not be stored explicitly.
 > 
 > If I understand you correctly, the problem is that a given
 > RunnableClosure may be executed using different threads at
 > different times.  I'm not every familiar with ThreadPoolExecutor,
 > but I assume that during each call to "run" it would be tied to a
 > single thread - or else lots of ThreadLocal stuff would break
 > (unless there is some API to re-bind those), and lots of stuff
 > would presumably break under the old model, too.  Right?
 > 
 > I'm not sure how you make use of RunnableClosure, but it seems
 > that if you need to tie an explicit Environment to a RunnableClosure
 > that shouldn't be difficult: Either a sub-class that overrides run,
 > or do it in the Scheme action Procedure that gets run.  The former
 > is probably better:
 > 
 > class MyRunnableClosure extends RunnableClosure {
 >     Environment env;
 > 
 >     public void run () {
 >        Environment.setCurrent(env);
 >        super.run();
 >     }
 > }
 > 
 > or something like that.
 > -- 
 > 	--Per Bothner
 > per@bothner.com   http://per.bothner.com/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]