[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)