[HN Gopher] Using Java's Project Loom to build more reliable dis...
       ___________________________________________________________________
        
       Using Java's Project Loom to build more reliable distributed
       systems
        
       Author : CHY872
       Score  : 114 points
       Date   : 2022-05-09 13:54 UTC (9 hours ago)
        
 (HTM) web link (jbaker.io)
 (TXT) w3m dump (jbaker.io)
        
       | [deleted]
        
       | _benedict wrote:
       | Cassandra already does this[1] (and a whole lot more besides to
       | introduce chaos to the simulation), and just accepts that there's
       | a huge penalty of pausing and scheduling threads.
       | 
       | I'm really looking forward to being able to use Loom to run much
       | more efficient cluster simulations.
       | 
       | [1]
       | https://cwiki.apache.org/confluence/display/CASSANDRA/CEP-10...
        
         | CHY872 wrote:
         | What sort of performance characteristics does Cassandra see
         | from its implementation? I was fairly impressed with the 2.5M
         | context switches per second (a fairly random unit, I know) I
         | saw from virtual threads.
         | 
         | Have you found that the approach has made it easier for you to
         | ship improvements to Cassandra?
        
           | _benedict wrote:
           | It's very slow, particularly since introducing byte weaving
           | to introduce chaos in concurrency-sensitive places. Presently
           | it takes a single thread in the region of twenty minutes to
           | simulate a cluster from startup to shutdown, and to run a
           | thousand linearisable operations (down from a couple of
           | minutes prior to those changes). I haven't got any numbers on
           | the rate of context switches per second, but it is certainly
           | a great deal less than 2.5M/s.
           | 
           | This kind of approach is in my opinion a _requirement_ for
           | work on distributed consensus protocols, which the Cassandra
           | community is improving at the moment: the upcoming 4.1
           | release has some major improvements to its Paxos
           | implementation that were validated by this simulation, and
           | the following release is expected to contain a novel
           | distributed consensus protocol we have named Accord, for
           | supporting multi-key transactions.
           | 
           | So, I'm not sure it has affected the speed or ease of
           | shipping improvements, rather than enabled a class of work
           | that would have previously been impossible to do safely
           | (IMO).
        
       | tadfisher wrote:
       | So Loom is just green threads? You have to implement a CPS
       | transformation on top? If so, great decision!
        
         | cogman10 wrote:
         | Loom is just green threads (referred to as virtual threads).
        
       | exabrial wrote:
       | This was linked in the article and is a fascinating read by
       | itself: https://shipilev.net/blog/2016/close-encounters-of-jmm-
       | kind
        
         | dang wrote:
         | Discussed at the time:
         | 
         |  _Close Encounters of the Java Memory Model Kind_ -
         | https://news.ycombinator.com/item?id=11955392 - June 2016 (65
         | comments)
        
       | kendallgclark wrote:
       | The FoundationDb team is working on distributed systems
       | simulation testing via a new startup... Antithesis. See
       | https://antithesis.com/
       | 
       | Stardog, enterprise knowledge graph platform, (stardog.com), is
       | an early adopter of Antithesis and we've found it to be very
       | helpful in HA Cluster, distributed consensus, etc.
       | 
       | Not a stakeholder, just a satisfied early adopter.
        
         | ryanworl wrote:
         | This is the first reference to Antithesis being used I've seen
         | since it was announced.
         | 
         | Can you describe what their tools are doing for you and how
         | you're integrating with them?
        
       | no_wizard wrote:
       | I feel like the unsung winner of Project Loom is going to be
       | Clojure. Its already immutable first data structures, it should
       | be relatively straightforward for the Clojure project to expose
       | the benefits of Project Loom to their ecosystem, as a language
       | its designed to fit well its execution model.
        
         | whalesalad wrote:
         | I think a Clojure with first class legitimate actor semantics
         | would be unreal. Clojure core will espouse async and tell you
         | why actors are bad but man I love the actor model.
        
         | chrisseaton wrote:
         | Loom threads have the same basic semantics as normal threads.
         | There's nothing special about them that relates to
         | immutability.
        
           | lgessler wrote:
           | I think GP's point is that immutable objects (which Clojure
           | uses "by default") can be easily used in concurrent settings.
           | Immutable objects can be shared without concern between
           | threads, whereas mutable objects may need to be copied or
           | have their operations synchronized somehow.
        
             | chrisseaton wrote:
             | > may need to be copied or have their operations
             | synchronized somehow
             | 
             | Maybe through some kind of non-preemptive user-space
             | scheduling you mean?
        
               | opnitro wrote:
               | Right, but you'd still need to synchronize that with some
               | concurrency primitives (like a mutex or semaphore) and
               | that has the potential for bugs. Whereas on an immutable
               | structure can't suffer from that problem, which can make
               | concurrent programming easier to reason about.
        
               | chrisseaton wrote:
               | > Right, but you'd still need to synchronize that with
               | some concurrency primitives (like a mutex or semaphore)
               | 
               | Why? If you know your thread won't be interleaved with
               | any other until you a well-defined point, how's that
               | different to using a mutex or semaphore?
        
         | pvorb wrote:
         | Why should Clojure benefit more from Loom than other languages?
         | I think it simplifies reactive/concurrent programming in any
         | JVM language.
        
           | no_wizard wrote:
           | Same reason I always felt extremely comfortable with
           | concurrent programming in F#. The immutable first principle
           | makes it easier to reason about what the program is doing
           | during concurrent execution.
           | 
           | Of course all projects will benefit from Loom. I am merely
           | positing that Clojure in particular could leverage this both
           | most quickly and to very deep positive effect, due to the
           | nature of the language itself putting immutability first,
           | which if I recall correctly they built up a pattern of
           | concurrent execution around already.
           | 
           | Kotlin too will be be able to optimize their concurrency
           | story.
           | 
           | I simply wanted to posit an observation I hadn't seen
           | elsewhere on the web about Project Loom yet.
        
       | electricshampo1 wrote:
       | Unlike goroutines, seems here you have control over the execution
       | schedule for the virtual threads if you provide an executor. This
       | is pretty great.
       | 
       | Think this will obsolete go over the next few decades.
        
         | didip wrote:
         | Java moves a lot slower so I don't think it will obsoletes Go.
         | 
         | If anything, if Loom is great, then it will keep Go on its toes
         | and hopefully Go will also evolved due to external pressure.
        
         | cogman10 wrote:
         | Not on the first go around. AFAIK, they are looking at exposing
         | more of the internal scheduling API but that's likely not going
         | to be a part of the initial release.
         | 
         | The executor services referred to in the blog are for the order
         | of execution of tasks on the virtual thread pool. For a
         | "virtualThreadExecutor" service, every task will get a virtual
         | thread and scheduling will happen internally.
         | 
         | You can still use a fixed thread pool with a custom task
         | scheduler if you like, but probably not exactly what you are
         | after.
        
           | CHY872 wrote:
           | This blogpost does rely on plugging in an executor. While the
           | API was removed, it's one private variable away (documented
           | in footnote). As you say, it seems like it's an 'on the way,
           | but later' thing - the last Loom preview I used (a while ago)
           | actually had the API so when I started drafting this post I
           | was unhappily surprised!
        
             | pron wrote:
             | Right, custom schedulers aren't quite ready for release yet
             | -- there's a small missing piece in the VM that's required
             | to fully preserve the spec, and they need a lot of testing
             | that we don't yet have -- so we decided to go ahead without
             | them and add them later.
        
             | cogman10 wrote:
             | IMO, they are focusing on the right thing here. Getting a
             | good virtual thread API GA will be paramount in the
             | decisions around scheduling and continuations in the
             | future.
             | 
             | Maybe a little disappointing for low level nuts and other
             | languages like kotlin, but the right move IMO. Virtual
             | threads alone will be a huge benefit to the ecosystem. The
             | other stuff will help, but won't have near the same impact.
        
               | CHY872 wrote:
               | Agreed. And the pluggable scheduling is still a key part
               | of it, just doesn't need to be a thing to get right out
               | of the gate. I'm honestly mega excited that Loom is even
               | a real thing that exists and that you can use.
        
         | jjice wrote:
         | I don't think it will. If everyone was clamoring for Java and
         | settled on Go only because of goroutines, then sure, but I
         | think Go was liked for a lot of reasons aside from that. I also
         | don't often see people complain about wanting more control over
         | the scheduler for Go (could be that I just miss those).
         | 
         | I'd be surprised if Go adoption plummeted because of this, but
         | who knows, I sure don't have a crystal ball.
        
           | lostcolony wrote:
           | Sane concurrency is -one- of the reasons people reach for Go,
           | and sure, that may no longer be a differentiator. But it's
           | definitely not the only one I've heard people toss around
           | (and, agreed, I've never heard anyone bemoan the lack of
           | control of the scheduler). In fact, the introduction of
           | virtual threads and no new memory semantics I think means it
           | still fails one of the main benefits of goroutines (channels
           | and default copying semantics); everything in JVM land by
           | default is still going to use shared memory and default pass
           | by reference semantics.
           | 
           | I think it's all a moot point though, as it basically just
           | demonstrates the next iteration of Paul Graham's Blub
           | Paradox. With every iteration of new improvements for the JVM
           | it reinforces the belief of many that the JVM is the best
           | tool for every job (after all, it now just got cool feature y
           | they just now learned about and can use and OMG Blub-er-Java
           | is so cool, who needs anything else?!), and reinforces the
           | belief of many others that the JVM is playing catchup with
           | other languages (it only just -now- got feature y) and there
           | are often better tools out there.
        
         | kjeetgill wrote:
         | One of the unsung heroes of go is how goroutines sit on top of
         | channels + select. Blocking and waiting on one queue is easy,
         | blocking and waiting on a set of queues waiting for any to get
         | an element is a good deal trickier. Having that baked into the
         | language and the default channel data-structures really does
         | pay dividends over a library in a case like this.
         | 
         | You can kinda do this with futures but I suspect it'll be
         | wildly inefficient. I really hope Java get's something to fill
         | this niche. We already have a menagerie of Queue,
         | BlockingQueue, and TransferQueue implementations. What's a few
         | more?
        
           | ackfoobar wrote:
           | > Having that baked into the language and the default channel
           | data-structures really does pay dividends over a library in a
           | case like this.
           | 
           | Kotlin coroutines have the bare minimum in the language, and
           | implement all those (channel, select, go(launch)) in
           | libraries. Could you explain what the dividends for Go are?
        
       | SemanticStrengh wrote:
       | Will loom get support for Blockhound?
       | https://github.com/reactor/BlockHound Blockhound supports both
       | reactive streams and Kotlin coroutines currently.
        
         | delusional wrote:
         | Project loom is about deprecating "non-blocking" and "reactive"
         | as a concept. The whole point is to just let the code block.
        
           | isbvhodnvemrwvn wrote:
           | How does it replace the backpressure mechanism from reactive
           | solutions?
        
             | ackfoobar wrote:
             | Send to a full `BlockingQueue`, producer will block.
             | Automatic backpressure.
        
       | zmj wrote:
       | I once did something similar in C# to deterministically test some
       | concurrency-heavy code (injecting custom TaskScheduler
       | instances). It gave me a lot of confidence that it actually
       | worked.
        
       | theptip wrote:
       | This is an interesting idea. I've been idly thinking about how to
       | make a framework for detecting DB anomalies in Django
       | applications (say, missing transactions, race conditions,
       | deadlocks etc.) which can be hard to detect. You can strap your
       | application to Jepsen but this is a more white-box approach and
       | probably harder to grok for the average Python developer.
       | 
       | I like the OP's idea of using a virtual thread implementation to
       | parallelize the application-layer, while having the test code
       | implement a custom executor to control the interleaving of the
       | units-of-work being scheduled. I can see a few ways this approach
       | could be used more widely; for example in Django you could write
       | a DB driver wrapper and have this as the "test executor". Or for
       | remote API requests, run the test code in green threads and then
       | have a test executor that intercepts and then then chooses how to
       | interleave the requests/responses.
        
       | rr808 wrote:
       | I spent the last few years really working hard to understand
       | async frameworks/libraries like VertX, Mutiny etc I've gone from
       | "I hate it" to "I can live with it". Now I dont have to. :) Yay.
        
       ___________________________________________________________________
       (page generated 2022-05-09 23:00 UTC)