Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #23508 > unrolled thread

Re: DI/wiring

Started bymarkspace <markspace@nospam.nospam>
First post2013-04-18 12:16 -0700
Last post2013-04-24 10:28 -0300
Articles 5 — 3 participants

Back to article view | Back to comp.lang.java.programmer

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: DI/wiring markspace <markspace@nospam.nospam> - 2013-04-18 12:16 -0700
    Re: DI/wiring Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2013-04-22 09:03 +0200
      Re: DI/wiring markspace <markspace@nospam.nospam> - 2013-04-22 10:59 -0700
        Re: DI/wiring Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2013-04-24 06:37 +0200
        Re: DI/wiring Arved Sandstrom <asandstrom2@eastlink.ca> - 2013-04-24 10:28 -0300

#23508 — Re: DI/wiring

Frommarkspace <markspace@nospam.nospam>
Date2013-04-18 12:16 -0700
SubjectRe: DI/wiring
Message-ID<kkpgls$6aq$1@dont-email.me>
On 4/18/2013 9:03 AM, Stefan Ram wrote:
>    I have »invented« myself something that also seems to be
>    known as »dependency injection« or »wiring«. I am doing it

I should have a look at Joerg's answer myself, but here's another idea.

Make an app context object that holds the state of your app.

class Context {
   Engine getEngine()....
   Printer getPrinter()...
}

Inject that into submodules in the code.  Submodules are larger than 
classes and can treat the context as immutable.  The context then 
becomes global but only for that module.  The idea is that you still get 
dependency injecting, but you can still test reasonably as well.

class SomeConfig {
   Context context;
   public SomeConfig( Context c ) { context = c; }

   public init() {
    Component c0 = new Component( context );

...
   }
}

class Component  {
   Context context;...
   public printIt() {
     context.getPrinter().do something...
   }
}

This reduces boilerplate but doesn't eliminate it.  For some projects it 
might be better to get a real dependency injection framework.




[toc] | [next] | [standalone]


#23565

FromDaniele Futtorovic <da.futt.news@laposte-dot-net.invalid>
Date2013-04-22 09:03 +0200
Message-ID<kl2n6i$3l5$1@dont-email.me>
In reply to#23508
On 18/04/2013 21:16, markspace allegedly wrote:
> On 4/18/2013 9:03 AM, Stefan Ram wrote:
>>    I have »invented« myself something that also seems to be
>>    known as »dependency injection« or »wiring«. I am doing it
> 
> I should have a look at Joerg's answer myself, but here's another idea.
> 
> Make an app context object that holds the state of your app.
> 
> class Context {
>   Engine getEngine()....
>   Printer getPrinter()...
> }
> 
> Inject that into submodules in the code.  Submodules are larger than
> classes and can treat the context as immutable.  The context then
> becomes global but only for that module.  The idea is that you still get
> dependency injecting, but you can still test reasonably as well.
> 
> class SomeConfig {
>   Context context;
>   public SomeConfig( Context c ) { context = c; }
> 
>   public init() {
>    Component c0 = new Component( context );
> 
> ....
>   }
> }
> 
> class Component  {
>   Context context;...
>   public printIt() {
>     context.getPrinter().do something...
>   }
> }
> 
> This reduces boilerplate but doesn't eliminate it.  For some projects it
> might be better to get a real dependency injection framework.

As a side note, since this approach has the drawback of requiring
additional constructor or method parameters (and hence targeted
factoring), I have in such cases often found it useful to provide the
context object via the threadlocal functionality.

In code terms, instead of:
  class Actor {
    void act( Context c ){ doSomethingWith( c.getXXX() ); }
  }
You'd have:
  class Actor {
    void act(){
      doSomethingWith( ContextHelper.getThreadLocalContext().getXXX() );
    }
  }

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#23569

Frommarkspace <markspace@nospam.nospam>
Date2013-04-22 10:59 -0700
Message-ID<kl3tkk$3hc$1@dont-email.me>
In reply to#23565
On 4/22/2013 12:03 AM, Daniele Futtorovic wrote:
>
> In code terms, instead of:
>    class Actor {
>      void act( Context c ){ doSomethingWith( c.getXXX() ); }
>    }

Just to be clear, I was advocating using constructors, not method 
parameters:

public class Actor {
   private Context c;
   public Actor( Context c ) {this.c = c}
   public void act() { doSomethingWith( c.getXXX() ); }
}

This is really really different:

> You'd have:
>    class Actor {
>      void act(){
>        doSomethingWith( ContextHelper.getThreadLocalContext().getXXX() );
>      }
>    }

Now actor does something different depending on what thread is invoking 
a method. My class was invariant with respect to the thread invoking its 
method.  No matter who calls "act()" the result will always be the same.

Since modern systems often use thread pools and the worker threads are 
supposed to be generic and often randomly assigned, I can't see too many 
cases where your thread local context is going to be useful.  Worse, if 
an generic worker thread has a context and then is assigned to another 
task... the results could be random and unpredictable, and really hard 
to debug as well.

I'm sure you must have some use case in mind where a thread local is 
useful, but I'm having a hard time seeing it.  It feels like you push 
the context/initialization problem into the threading system, where it's 
actually going to be harder to manage.  In a system that was designed 
from the ground up to support contexts attached to threads, OK it might 
work, but in many existing systems it seems difficult to add.

[toc] | [prev] | [next] | [standalone]


#23610

FromDaniele Futtorovic <da.futt.news@laposte-dot-net.invalid>
Date2013-04-24 06:37 +0200
Message-ID<kl7nco$25q$1@dont-email.me>
In reply to#23569
On 22/04/2013 19:59, markspace allegedly wrote:
> On 4/22/2013 12:03 AM, Daniele Futtorovic wrote:
>>
>> In code terms, instead of:
>>    class Actor {
>>      void act( Context c ){ doSomethingWith( c.getXXX() ); }
>>    }
> 
> Just to be clear, I was advocating using constructors, not method
> parameters:
> 
> public class Actor {
>   private Context c;
>   public Actor( Context c ) {this.c = c}
>   public void act() { doSomethingWith( c.getXXX() ); }
> }

Yes; this is why I spoke of "constructor or method parameters".

See, the problem, or issue, with this approach is that you make the
context part of the actor's state. Meaning the actor is bound to the
context, rather than being context-independent. For instance, the
component wouldn't be reusable for a different context.

Now, there may be situations where that would be the right thing to do.
Yet, because of that, this approach to me is inferior to passing the
context to the main actor method (the method that encapsulates the unit
of work).

> This is really really different:
> 
>> You'd have:
>>    class Actor {
>>      void act(){
>>        doSomethingWith( ContextHelper.getThreadLocalContext().getXXX() );
>>      }
>>    }
> 
> Now actor does something different depending on what thread is invoking
> a method. My class was invariant with respect to the thread invoking its
> method.  No matter who calls "act()" the result will always be the same.
> 
> Since modern systems often use thread pools and the worker threads are
> supposed to be generic and often randomly assigned, I can't see too many
> cases where your thread local context is going to be useful.  Worse, if
> an generic worker thread has a context and then is assigned to another
> task... the results could be random and unpredictable, and really hard
> to debug as well.

I'll have to disagree with you here. All systems that use thread pools
will involve some sort of dispatch mechanism that consumes a queue of
work units. I do not believe it is far fetched to imagine that the
dispatch mechanism would run as exemplified in the following:

  while take-from-queue
   set-up-context
   try {
    execute-task
   } finally {
    clean-up-context
   }

The only situation, then, where the ThreadLocal wouldn't work is when
the work units are executed on multiple threads. I may be wrong, but I
do not see this as being the majority of cases -- to the contrary.

> I'm sure you must have some use case in mind where a thread local is
> useful, but I'm having a hard time seeing it.  It feels like you push
> the context/initialization problem into the threading system, where it's
> actually going to be harder to manage.  In a system that was designed
> from the ground up to support contexts attached to threads, OK it might
> work, but in many existing systems it seems difficult to add.

It is true that it is more fragile, and for that reason alone may be
legitimately rejected, I'll grant you that. But it is not difficult to
add; quite the contrary, it is much easier to add to an existing system
than the one you suggested, because it does not involve any change in
the API (only to the implementation).

Now, don't get me wrong, I'm not trying to suggest this is anywhere the
be-all and end-all of programming techniques. Indeed, because it is
fragile and less explicit (and hence more difficult to grasp) than the
other way (passing a context to the actor's method), the latter is my
preferred and indeed the standard approach I opt for when designing a
piece of code that involves a dispatch mechanism (which is most of
them). I merely intended to mention that other possibility for the record.

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#23623

FromArved Sandstrom <asandstrom2@eastlink.ca>
Date2013-04-24 10:28 -0300
Message-ID<F5Rdt.1871$FS4.989@newsfe12.iad>
In reply to#23569
On 04/22/2013 02:59 PM, markspace wrote:
> On 4/22/2013 12:03 AM, Daniele Futtorovic wrote:
>>
>> In code terms, instead of:
>>    class Actor {
>>      void act( Context c ){ doSomethingWith( c.getXXX() ); }
>>    }
>
> Just to be clear, I was advocating using constructors, not method
> parameters:
>
> public class Actor {
>    private Context c;
>    public Actor( Context c ) {this.c = c}
>    public void act() { doSomethingWith( c.getXXX() ); }
> }
>
> This is really really different:
>
>> You'd have:
>>    class Actor {
>>      void act(){
>>        doSomethingWith( ContextHelper.getThreadLocalContext().getXXX() );
>>      }
>>    }
>
> Now actor does something different depending on what thread is invoking
> a method. My class was invariant with respect to the thread invoking its
> method.  No matter who calls "act()" the result will always be the same.
>
> Since modern systems often use thread pools and the worker threads are
> supposed to be generic and often randomly assigned, I can't see too many
> cases where your thread local context is going to be useful.  Worse, if
> an generic worker thread has a context and then is assigned to another
> task... the results could be random and unpredictable, and really hard
> to debug as well.
>
> I'm sure you must have some use case in mind where a thread local is
> useful, but I'm having a hard time seeing it.  It feels like you push
> the context/initialization problem into the threading system, where it's
> actually going to be harder to manage.  In a system that was designed
> from the ground up to support contexts attached to threads, OK it might
> work, but in many existing systems it seems difficult to add.
>
I can think of one right now, one that is in production in a fairly 
major J2EE/JEE system I am familiar with.

The idea was/is to implement a persistent conversation, and this 
implementation goes back about 7 years, in the context of JSF 1.x and 
JPA. Basically an application-managed entity manager needs to kept 
around, one for each application user, from a defined EM-creation 
checkpoint to a defined EM-commit/rollback checkpoint. This is needed 
because money is involved and the real-world scenario demands it. It is 
not possible to commit per-request, for much of the business state.

Between HTTP requests it's reasonable to keep a user's EM in their HTTP 
session. *During* requests the specific conversational EM assigned to 
that user must be made available wherever it's required in code - a very 
convenient way of doing that is to place the user EM into a ThreadLocal 
in the 1st JSF phase, in a helper class, and provide a getter to allow 
the user's HTTP request thread to retrieve that "special" EM as needed 
in any method.

I think you'll realize that something like an ApplicationScoped JSF 
managed bean would not work here. It's technically possible for B.L. or 
datalayer code to access a JSF managed bean, if you assume that that top 
layer is there, but it's an unpleasant picture. Much better to have the 
user EM's kept in a ThreadLocal in a data layer helper class, since that 
makes architectural sense.

I might add, this described implementation is pre-Servlet 3 and no async 
processing is involved.

AHS

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web