To be clear, SLF4J only provides an MDC API and doesn’t implement the MDC. It 
delegates that to an implementation - Log4j 2 or Logback. Obviously, my concern 
would be to get Log4j 2 to work the way it needs to. If it requires additional 
help from the JDK library then there is only so much I can do. But if work is 
being asked of the JDK then, IMO, it should be general enough that it can be 
used for more than just CompleteableFuture.

Ralph

> On Mar 22, 2018, at 11:32 AM, Dean Hiller <dhil...@twitter.com> wrote:
> 
> oh, I see
> 
> yes, that code could be done in CompletableFuture though...Executor does not 
> have to be touched based on the scala code I read.  ie. you create a new 
> Runnable that reads the last Local context transferring into a ThreadLocal 
> until the next transfer is needed(at each .thenApply/.thenCompose 
> boundaries).  
> 
> There are weird methods and I would just not worry about those except as it 
> relates mostly to getting slf4j's MDC to work.
> 
> On Thu, Mar 22, 2018 at 12:27 PM, Ralph Goers <ralph.go...@dslextreme.com 
> <mailto:ralph.go...@dslextreme.com>> wrote:
> My point is that I don’t think this is the only place the problem occurs. I 
> have seen similar questions on the Log4j mailing list where users want to be 
> able to do this for thread pools they create via Executors and don’t want to 
> have to do the ThreadLocal propagation themselves. If a CompleteableFuture 
> uses an Executor under the covers then it could leverage the same solution.
> 
> Ralph
> 
> 
>> On Mar 22, 2018, at 11:21 AM, Dean Hiller <dhil...@twitter.com 
>> <mailto:dhil...@twitter.com>> wrote:
>> 
>> I am basically asking for someone to copy the solution in twitter 
>> Future.scala(which uses Local.scala) into CompletableFuture.java, yes.
>> 
>> ie. I should be able to say Local.set("something", value) and in 
>> CompletableFuture when .map is called, it will ensure the key/values are 
>> transferred across threads.  Local.scala internally uses a ThreadLocal up 
>> into the point of .map/.flatMap (ie. thenApply/.thenCompose).  At that 
>> point, it transfers it across threads into a new ThreadLocal.
>> 
>> ie. the answer on how to do it exists here(search on Locals and see it in 
>> the respond method which is called by map and flatMap)..
>> 
>> https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Future.scala
>>  
>> <https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Future.scala>
>> 
>> Here is the Local class that clients use and the Future uses to transfer 
>> contexts across map/flatMap
>> https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Local.scala
>>  
>> <https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Local.scala>
>> 
>> (I do apologize if you do not read scala code, but the answer is there and 
>> just in a different language)
>> 
>> later,
>> Dean
>> 
>> 
>> On Thu, Mar 22, 2018 at 11:40 AM, Ralph Goers <ralph.go...@dslextreme.com 
>> <mailto:ralph.go...@dslextreme.com>> wrote:
>> Having read several of the threads I think I have a better understanding of 
>> the problem. This sounds similar to problems that occur with any application 
>> that has a way of doing asynchronous processing with with thread pools. Java 
>> has unfortunately not provided a good way that I know of to pass a 
>> ThreadLocal from one thread to a worker thread. I am guessing that is what 
>> you are really asking for is some sort of property on the Executor that 
>> tells it to pass the ThreadLocals from one thread to the worker that 
>> performs action on its behalf.
>> 
>> Ralph
>> 
>> > On Mar 22, 2018, at 10:13 AM, Ralph Goers <ralph.go...@dslextreme.com 
>> > <mailto:ralph.go...@dslextreme.com>> wrote:
>> >
>> > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. Both 
>> > are based on ThreadLocal variables. If I understand what you are saying, 
>> > the problem is that ThreadLocals do not work as you you would expect when 
>> > using CompleteableFutures?
>> >
>> > Ralph
>> >
>> >> On Mar 22, 2018, at 7:05 AM, Dean Hiller <dhil...@twitter.com 
>> >> <mailto:dhil...@twitter.com>> wrote:
>> >>
>> >> slf4j is pretty much the defacto logging standard these days allowing one
>> >> to bring in libraries using any logging framework.  (commons logging fell
>> >> short and had classloading bugs).
>> >>
>> >> Summary: MDC works fine in twitter scala Futures but not java
>> >> CompletableFutures.
>> >>
>> >> Unfortunately, one of the best features(brought over from log4j which is
>> >> also broken now) is the MDC. The MDC no longer works with
>> >> CompletableFutures so people will have to move to scala where it does 
>> >> work.
>> >>
>> >> Documentation on MDC if you don't know what that is....
>> >> https://logback.qos.ch/manual/mdc.html 
>> >> <https://logback.qos.ch/manual/mdc.html>
>> >>
>> >> or for a more concrete example, as a developer a request comes in and you
>> >> set MDC.put("requestId", requestId) and now whenever you log, that request
>> >> id is added to your log line.  No developer has to 'remember' to add it
>> >> every time he adds a log statement.
>> >>
>> >> This is due to the lack of Local.java file that should exist and transfer
>> >> context over the .thenApply/.thenCompose methods like twitter Futures has
>> >> in scala land. (see Local.scala in twitter Futures and the twitter Future
>> >> code for how this works)
>> >>
>> >> In scala, it works and we have all the same methods as CompletableFuture
>> >> for the most part and yes, we can't transfer the context over some 
>> >> methods,
>> >> but at least our MDC in scala servers is not broken.
>> >>
>> >> Lack of this feature is forcing our hand to code in scala where it is not
>> >> broken.  ie. we need logging and we definitely need the request id or
>> >> client id or whatever attached automatically to every log(as humans have
>> >> trouble remembering to add it themselves every single time).
>> >>
>> >> thanks for reconsidering,
>> >> Dean
>> >>
>> >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller <dhil...@twitter.com 
>> >> <mailto:dhil...@twitter.com>> wrote:
>> >>
>> >>> All, this post is all about 3rd party code that I do not control so
>> >>> therefore the solutions above do not work as those libraries may predate 
>> >>> my
>> >>> library.  more specifically.....
>> >>>
>> >>> Martin,
>> >>>  If I roll my own slf4j MDC only works in my code and stops working in
>> >>> 3rd party code!  because the 3rd party code does not transfer the 
>> >>> context.
>> >>>
>> >>> Viktor,
>> >>> You hit the head on the nail with "It's easy to lose context when
>> >>> intermediate libraries/Executors".  This is solved on twitter futures 
>> >>> until
>> >>> we hit libraries not using twitter futures because no matter the 
>> >>> executor,
>> >>> the future transfers the context for us the way it was written.
>> >>>
>> >>>  "It's unclear what fan-in behaviors like zip, merge etc mean in terms
>> >>> of what the local values should be?"
>> >>> This is a very good question.  I wonder what twitter futures do here.  I
>> >>> would be ok with dropping the context in this case or combining it.  I do
>> >>> not really care yet here since I have not run into it but it is a very 
>> >>> good
>> >>> question and would need a lot of thought
>> >>>
>> >>> Josh,
>> >>>  I cannot expect all 3rd party libraries that are brought in will be
>> >>> using ContextPropagatingExecutor so that solution breaks down as Viktor
>> >>> eludes to.
>> >>>
>> >>> Alex,
>> >>>  tuples do not solve the issue.  in fact twitter futures have a
>> >>> Local.scala file that does solve the issue.  The main issue is 3rd party
>> >>> code and having the context continue into "unknown code" using
>> >>> CompletableFuture.  I cannot control that code BUT want every log.info 
>> >>> <http://log.info/> in
>> >>> that code to use and log the request id.  it is awesome at twitter as I 
>> >>> can
>> >>> just follow that request id in the logs.  If CompletableFuture had such a
>> >>> context, I could transfer this info into it and into the 3rd party java
>> >>> libraries.
>> >>>
>> >>> I am writing a webserver for fun based on CompletableFutures and 
>> >>> therefore
>> >>> cannot control the controllers as the app developer writes that and the
>> >>> request id stops getting logged on the request path which is mostly
>> >>> .thenApply and .thenCompose.  even if the Controllers do you my future,
>> >>> they will bring in libraries NOT using my future :(
>> >>>
>> >>> thanks
>> >>> Dean
>> >>>
>> >>>
>> >>>
>> >>>
>> >>>
>> >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko <oleksandr.ote...@gmail.com 
>> >>> <mailto:oleksandr.ote...@gmail.com>>
>> >>> wrote:
>> >>>
>> >>>> Why would someone want to rely on state they cannot control?
>> >>>>
>> >>>> Is the idea to subvert some API that does not provide a way to pass
>> >>>> state? This is strange especially in the context of Scala, where you can
>> >>>> easily form tuples.
>> >>>>
>> >>>> Alex
>> >>>>
>> >>>> On 22 May 2017, at 20:44, Martin Buchholz <marti...@google.com 
>> >>>> <mailto:marti...@google.com>> wrote:
>> >>>>
>> >>>> There's not likely to be any support for local context anywhere in
>> >>>> java.util.concurrent, but it seems not too hard to roll your own support
>> >>>> with a custom executor to be used with CompletableFuture that kept 
>> >>>> track of
>> >>>> any local context.
>> >>>>
>> >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo <pavel.ra...@oracle.com 
>> >>>> <mailto:pavel.ra...@oracle.com>>
>> >>>> wrote:
>> >>>>
>> >>>>> General questions on concurrency in Java should be asked here:
>> >>>>>
>> >>>>>  http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest 
>> >>>>> <http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest>
>> >>>>>
>> >>>>>> On 18 May 2017, at 21:57, Dean Hiller <dhil...@twitter.com 
>> >>>>>> <mailto:dhil...@twitter.com>> wrote:
>> >>>>>>
>> >>>>>> Way more detail here...
>> >>>>>>
>> >>>>>> http://stackoverflow.com/questions/37933713/does-completable 
>> >>>>>> <http://stackoverflow.com/questions/37933713/does-completable>
>> >>>>> future-have-a-corresponding-local-context
>> >>>>>>
>> >>>>>> So I was wondering if this was going to be added at some point to the
>> >>>>> jdk
>> >>>>>> as I could not figure out how to set something so it was still
>> >>>>> available on
>> >>>>>> the thread at a later time when traversing async thenCompose,
>> >>>>> thenAccept.
>> >>>>>>
>> >>>>>> thanks,
>> >>>>>> Dean
>> >>>>>
>> >>>>>
>> >>>> _______________________________________________
>> >>>> Concurrency-interest mailing list
>> >>>> concurrency-inter...@cs.oswego.edu 
>> >>>> <mailto:concurrency-inter...@cs.oswego.edu>
>> >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest 
>> >>>> <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>> >>>>
>> >>>>
>> >>>>
>> >>>
>> >>
>> >
>> >
>> >
>> 
>> 
>> 
> 
> 

Reply via email to