-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Making SuspendableCallable @Suspendable { .. }
work again with Kotlin
#121
Comments
I'd be willing to contribute in whatever way with fixing this issue so if anything's needed from my end please do let me hear! |
Can you confirm you're using 0.7.4-SNAPSHOT? What happens if you remove the "@Suspendable" annotation from your lambda? I'll be hearing from the Kotlin team, apart from that I think adding a Kotlin annotation and recognizing it it in the |
Yes, I can confirm this. The two jar libraries I use come from the sonatype snapshot repository and are:
The Kotlin version I use in my project is Removing it will probably result in it not being instrumented at all, but I will test that and get back to you. Adding a Kotlin annotation would probably be the best way to go - it leaves the Java annotations as-is which is working all good but if a new annotation would be able to hint the instrumenting then that would be the cleanest solution I think. When there's anything I need to test furthermore please do let me hear. |
Regarding removing the annotation: it skips instrumenting the lambda code in general so it doesn' work. |
I think I'm close to contributing a fix - I've been hacking around to see if I would be able to get it fixed and after adding a secondary annotation in the quasar-kotlin module and making that a recognized instrumentation annotation I think things worked out the way it used to. Currently all tests pass but I need to verify if the inner workings of my project are as with M12. Once this all works I can submit a pull request. |
Thanks a lot for looking into this! I'd really like to avoid embedding knowledge about Kotlin in I've just gone through a review of such classifier and I think the current Also, this test will let all inner classes in Kotlin sources proceed to the following logic, which marks for (potential) instrumentation all the methods that implement any of Kotlin runtime's "suspendable-supers" listed in the array (that is, the ones that define Kotlin's callable features in the runtime). This means it should cover lambdas as well (I think they inherit from |
An example of my use case is this:
It's a library providing blocking calls for a game. As you can see, a lambda is passed to a repository to assign it to a trigger to run later on when it's triggered. I did actually try as you said without the Is there anything else I'd be able to change to let the pull request be merged? To me it seems like a viable solution because it works fine for projects without |
Really strange. Could you provide the stacktrace of your issue with verification turned on, when removing the |
Triggering it does this:
Which lets the executor invoke the script. That creates a new Fiber and lets the fiber invoke the lambda. The calling part is annotated with
|
Can you also provide the stacktrace? |
Going to be a bit harder as I'll have to revert all my fixes and make some changes, but I'll do my best to get this. If I recall correctly, it just throws the well-known "did you forget to instrument something?' with the methods annotated with |
Thanks. Ok so the code invoking the lambda in |
Quite interesting indeed, because that's pretty much what my code does too. I'm not sure what the main difference is really. All I know is that it didn't properly instrument my variant. I'll do some more research, seeing if I can come up with a reason why exactly the way I used the lambdas wasn't working. Thanks for your time 👍 |
This is actually more similar to your code: @Suspendable
private fun callSusLambda(f: (Int) -> Unit, i: Int) =
Fiber(scheduler, object : SuspendableCallable<Boolean> {
@Suspendable override fun run(): Boolean {
f(i)
return true
}
}).start().get()
@Test fun testFunLambda() {
assertTrue(callSusLambda({ Fiber.sleep(10) }, 1))
} But it still passes. This is even more similar though: @Suspendable
private fun callSusLambda(f: (Int) -> Unit, i: Int) =
Fiber(scheduler, SuspendableCallable {
f(i)
true
}).start().get()
@Test fun testFunLambda() {
assertTrue(callSusLambda({ Fiber.sleep(10) }, 1))
} And this one actually breaks with:
I think that class must be an anonymous So there's actually an issue but the scope is narrower than previously thought (that is, interaction with Java8 functional interfaces) and at least there's a workaround: passing an object instance explicitly implementing If you want you could inspect the instrumentation logs and decompile the class (before and/or after instrumentation) to check this is indeed the case. Still if you want, you could try leaving Thanks for your time! |
I see now, awesome, glad we were able to narrow this down together. Should I make an effort to edit And I'm really happy to contribute, don't mention it :) |
Contributions are always very welcome although it can require some patience to refine them together to the point they can be included. It's also a further journey to study more of Quasar, if you are interested (and you've got time). Before you do that though, I'd like first to hear from the Kotlin guys if this M13 limit of Java annotations can be worked around somehow, maybe there's (or there'll be) a way to declare them applicable to expressions. I'll get back here with more insight. |
I've actually found a member of Kotlin saying that M14 will have this reenabled. This was in a question from someone asking why he couldn't apply an annotation on his lambda: https://devnet.jetbrains.com/message/5558919;jsessionid=65679B2EC5A3E2C88777404D3FF5E9AF Dmitry Jemerov there replied that M14 will allow the annotations on them again, yet I'm not 100% sure how sure that all is because he mentions the documentation is wrong - giving me the idea that it's going to be a somewhat persisiting change. I guess time or a developer will tell what they will do with it. And yes, I'm actually very interested in the inner workings and whatnot, and I've got plenty of time hence why I want to help fix this instead of applying the fix to my local project and continuing 😄. |
Thanks for pointing out. That's actually a bit of a strange change also because usually in Kotlin idioms get deprecated (and a refactoring in Idea is provided) before being forbidden altogether. If it's going to be re-enabled, considering the limited scope of the issue and the fact that there is a workaround, I think probably it's not worth fixing. As for your project you could just use the workaround until M14. But of course enjoy using (and studying) Quasar! |
I'm not 100% sure on if it gets re-enabled, but for now I'll just stick to my local edits. If it turns out not to be re-enabled, I'll happily provide the fix in a pull request. If you manage to hear something from the Kotlin team I'd be happy to hear too! |
Sure, will update here, we can leave the PR and the issue open are until more info arrives and we decide what to do. |
Awesome, I receive notifications on this issue + the PR so when there's any news I'll get back immediately :) |
SuspendableCallable @Suspendable { .. }
work again with Kotlin
It looks like the Kotlin change has already been committed and M14 is being released next week (very same thread you cited). |
@circlespainter That's quite a fast drop of M14. Hopefully the upgrade process in IntelliJ IDEA will be better than what we currently have (not working for almost all of my friends). |
Hi @circlespainter, to get back to you real quickly after updating to M14 it seems that the change has indeed been made and I can annotate my lambda's like before. A persisting issue I have though is that it seems to fail to be able to check super inheritance when the class is missing on the classpath for whatever reason.
I'm not sure if this is already fixed on master, but it might be an idea otherwise to make it print a warning if the resolving failed and return |
A note on the above: I was missing a kotlin compiler library which resulted in a missing class. Still, it might be very useful to know which class it misses when that method fails :-). |
@Velocity- Will add an assertion w/message about that for now, you can enable it during development with the |
A new |
Since M13 was pushed out the
co.paralleluniverse.fibers.Suspendable
annotation can no longer be applied to a lambda as it could before because the annotation now needs to have the Kotlin targetAnnotationTarget.EXPRESSION
or else it will simply not compile. An example would be:The above does not compile anymore because the annotation misses the target. I replaced the class by a custom variant using the Kotlin expression type:
That does compile fine and results in compilation succeeding for the previously described example. However, replacing the packaged Suspendable annotation with the custom Kotlin variant seems to break the library (it does not detect instrumented methods anymore), so I'm looking for some kind of input on having this nifty feature working again.
Cheers.
The text was updated successfully, but these errors were encountered: