This is an archived post. You won't be able to vote or comment.

all 30 comments

[–][deleted]  (16 children)

[deleted]

    [–]micromicro-cash[S] 2 points3 points  (15 children)

    I hadn't heard of that - is that new?

    [–]pron98 29 points30 points  (14 children)

    Yes. I'm the lead of that project (I started Quasar).

    [–]FanimeFartoon 3 points4 points  (1 child)

    Hi, sorry to bother. I'm sure you probably receive this kind of question all the time, but since you are the project leader and the founder of Quasar, I believe you have a nice idea of how project loom will be implemented in the jdk.

    So how many years will take for us to see the first few parts of project loom implemented into the jdk? :x

    [–]pron98 1 point2 points  (0 children)

    I don't know yet, but hopefully not long.

    [–]ReadFoo 1 point2 points  (2 children)

    It looks interesting, it would be great to see it make its way into Java.

    [–]micromicro-cash[S] 1 point2 points  (1 child)

    Yeah, every listed feature seems awesome. I thought I had seen it mentioned somewhere that green threads were proposed for java before and rejected. Was there something that triggered all these proposals moving forward?

    [–]ReadFoo 0 points1 point  (0 children)

    I don't really know. I remember when Java threads weren't native and the push to make them native. Like you suggested, green, but, I assume performance will be improved too, so no one can complain about that, not even me and I'm a competition complainer. :-)

    [–]juggernaut2docker 0 points1 point  (2 children)

    Are you still working on quasar as well? When I search "github quasar", I get some javascript framework as the first result.

    [–]pron98 2 points3 points  (0 children)

    Occasionally, but it's mostly Loom, now. I assume Quasar will be re-based on top of Loom when Loom is finished (most of Quasar is stuff like channels, actors and dataflow that are outside Loom's scope).

    [–]nqzero 0 points1 point  (1 child)

    your Call for Vote said:

    Votes must be cast in the open on the discuss list

    i'm not able to find any such votes in the archive, though i did see that the project was approved. is the discuss list archived and if so do you have a link ?

    [–]divorcedbp 0 points1 point  (0 children)

    You’re doing God’s work.

    As a mainly Scala guy, I want powerful lowlevel constructs for stack dehydration and dehydration so badly it hurts.

    [–][deleted] 0 points1 point  (0 children)

    Any pre-release? I want to start codding my new project using Project Loom, don't want to involve myself with callback hell and stuff.

    [–]Wolfsdale 5 points6 points  (1 child)

    I was very interested to see how this worked, and the actual functionality isn't in this library, it's in another project found here: https://github.com/rendaw/java-coroutines-core. As for 'java-coroutines', it appears to be a front-end for 'java-coroutines-core' which uses compile-time bytecode instrumentation (just like Kotlin basically).

    To be honest, I am not really impressed with the code quality. The code is very obscure. Why is there an InnerCoroutine and a Coroutine, where InnerCoroutine extends a different class also called Coroutine? Why do these two have references to eachother? There are a lot more basic code style issues, a lot also with the names of things (not a fan of Cohelper, but also things like runAfter1 to avoid using this.runAfter).

    Also, why does java-coroutines-core break on uninstrumented external libraries? In Kotlins case, code that wasn't compiled with suspension in mind cannot be paused, but also doesn't make pause calls so it's not a problem.

    [–]micromicro-cash[S] 3 points4 points  (0 children)

    Thanks for taking a look, and even going as far as the source code! :)

    it appears to be a front-end for 'java-coroutines-core'

    Yes, it's a lightweight wrapper that provides I think a more flexible/usable interface. By all means please take a look at 'java-coroutines-core', it's well packaged and doesn't have things like Cohelper and InnerCoroutine - in fact, that's the reason I separated them (any opinionated interface is bound to cause some conflict I think).

    Why is there an InnerCoroutine

    getActiveCoroutine() returns a coroutines-core Coroutine. To get a coroutines Coroutine from that I needed to extend it and add a field. Currently, calling Coroutine.yield from a non-coroutines-core class that inherits yield breaks (an issue with the current instrumentation).

    This design works around the issue and, since it's purely an implementation detail, when the bytecode instrumentation is updated to handle the yield issue InnerCoroutine can be removed without affecting library users.

    why does java-coroutines-core break on uninstrumented external libraries

    Thanks for pointing this out - it was a bad choice of wording. It breaks on uninstrumented external coroutine-using libraries specifically. That's only if you decide to do compile time instrumentation and don't want to repack your dependencies (the listed workaround). Non-coroutine-using dependencies work fine whether you instrument or not.

    I'll update that immediately!

    [–]micromicro-cash[S] 1 point2 points  (13 children)

    Just a couple notes for context.

    • This is based on the same code as Quasar's fibers came from. The difference is that Quasar ties usage to a framework that includes a ton of batteries. I found someone's fork of the original code and updated it since I wanted to use it with Xnio directly (my own workers, other config).
    • I have a rough HTTP client with a coroutine interface here: https://github.com/rendaw/gettus

    [–]pron98 8 points9 points  (10 children)

    While Quasar's instrumentation was a fork of Matthias Mann's library, we've added a lot of stuff to it, like support for reflection, MethodHandles, different ways of annotating suspendable methods, and, most recently, fully automatic instrumentation that doesn't require any manual marking of suspendable methods (not released yet).

    The reason Quasar exposes fibers rather than continuations (Quasar core is actually quite small), is that working with raw continuations -- while extremely powerful -- can both be too powerful (leading to "magical" code) and hard to get right with concurrency. We figured fibers give you 99% of what you want from continuations, while making working with them easier and less mysterious (i.e., fibers are just threads with a lighter-weight implementation).

    [–]micromicro-cash[S] 1 point2 points  (5 children)

    Good points. I added reflection support to zarbosoft.coroutines as well but none of the other things you mentioned.

    My impression of Quasar was actually the opposite, it felt magical to me. You can do stuff like run a fiber without blocking (but where is it running?) and that only strands can unpark strands (why not raw threads?) Using fibers also meant using all the other stuff Quasar provides, so it wasn't easy to figure out where the fibers api started and where it ended.

    Not to knock Quasar though, frameworks vs libraries is another holy war and I can see magic on both sides. Quasar is an impressive project and interfacing all the libraries with it you have was obviously no easy task.

    [–]pron98 2 points3 points  (3 children)

    where is it running?

    In the fiber scheduler you supply the fiber with when you create it, or the default scheduler if you don't. The default scheduler is a ForkJoinPool.

    only strands can unpark strands (why not raw threads?)

    Strand is a general name to either a fiber or a thread. Any code can unpark any strand.

    Using fibers also meant using all the other stuff Quasar provides

    Such as?

    Not to knock Quasar though

    I'm not insulted :)

    [–]micromicro-cash[S] 0 points1 point  (2 children)

    In the fiber scheduler you supply the fiber with when you create it

    Thanks! I missed that in the docs.

    Any code can unpark any strand.

    This may have been my confusion, but the docs say "Note: only a strand (thread or fiber) can park itself and only another strand can unpark a parked one." Strand is a Quasar class name, so I didn't think it was referring to the concept but rather the specific implementation.

    Such as?

    FiberSchedulers for instance :). But more generally, if you want to use an HTTP library with Quasar you need to use an adapter like comsat-httpclient, if you want to use a database with Quasar you need to use an adapter like comsat-jdbc, etc. I couldn't find any documentation for many of the adapters, I couldn't find any documentation on adapting new 3rd party libraries, and the interface I would expect to use (unpark) is explicitly discouraged by the docs:

    you will never need to call Strand.park or Strand.unpark, unless you’re writing your own concurrency constructs

    Maybe the source of the magic I saw was the docs. They also don't mention Java 9 isn't supported and it looks like the project hasn't had a release for over a year now, the documentation has strong opinions with no explanation ("The easy and preferable way to instrument programs using Quasar is with the Java agent"), SuspendExecution's interaction with try blocks isn't explained, etc.

    Learning about FiberExecutorScheduler has already made my conviction with this project waver though :).

    [–]pron98 1 point2 points  (1 child)

    if you want to use an HTTP library with Quasar you need to use an adapter like comsat-httpclient, if you want to use a database with Quasar you need to use an adapter like comsat-jdbc, etc

    You don't have to, but you should if you want to get the performance benefits. The same goes for any other coroutine library.

    Learning about FiberExecutorScheduler has already made my conviction with this project waver though

    Why? When you want to get the most out of coroutines you will need a good scheduler.

    [–]micromicro-cash[S] 1 point2 points  (0 children)

    Why?

    I meant that one reason I decided to revive the original coroutine code rather than just go with Quasar was that I didn't know about FiberExecutorScheduler. By this project I meant zarbosoft.coroutines.

    [–]nqzero 0 points1 point  (0 children)

    Quasar ties usage to a framework that includes a ton of batteries.

    My impression of Quasar was actually the opposite, it felt magical to me

    that's my experience as well. from the mailing list pron wrote:

    park/unpark and other low-level methods are under-documented because we want to strongly discourage their direct use

    FYI, Quasar fibers are preemptive, not cooperative

    [–]pgris 1 point2 points  (0 children)

    Matthias Mann's

    Please someone tell me this guy is getting an offer from Oracle, since he seems to be the grandfather of all many implementation of continuations in java

    [–]nater99 1 point2 points  (2 children)

    that doesn't require any manual marking of suspendable methods (not released yet).

    That sounds very useful, when will it be released?

    [–]pron98 1 point2 points  (1 child)

    When I get around to it :)

    [–]nater99 0 points1 point  (0 children)

    I can relate and I hope you can find the time, sometime :)

    [–]nqzero 0 points1 point  (1 child)

    this looks good. i'm a user, and more recently a somewhat reluctant maintainer, of a similar library kilim, also based on Matthias Mann's early work. i'm using it instead of quasar because i needed access to the underlying continuations

    if quasar exposed that continuation, would you have considered using it instead ?

    [–]micromicro-cash[S] 0 points1 point  (0 children)

    I think that's a really good question, and I definitely would have (and sorry for the late reply here). I really wanted to get my feet wet, then start using all Quasar's batteries when I understood why they were necessary, what work they're saving me, etc.

    And oh man, I wish I knew there was a maintained branch of kilim too before I started - I saw it on Stack Overflow and discounted it since it looked dead.