-
Notifications
You must be signed in to change notification settings - Fork 24
Consider replacing retrofit2 #96
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
Comments
@The-Funk I think we can do a switch to ktor fairly easily, just a bunch of grunt work to switch over. That said, I don't really have any experience with GraalVM. To verify the RAM issue, would it just be a difference of using GraalVM when running the server? |
It's not really a RAM issue, as much as a cost savings. GraalVM executables simply eat less RAM than regular JVM jars, etc. The issue I'm facing is that Retrofit doesn't work with GraalVM. I should preface, to my knowledge there are not a lot of people using GraalVM native images just yet. The technology is just now maturing. GraalVM native image is a tricky beast due to runtime reflection in Java and Kotlin. Basically, at build time, the compiler determines all of the Java classes that are needed for the execution of the program, and those are all compiled into a single native binary. That binary should include everything needed to run the program and nothing else, so native images tend to be really lean, have a much smaller memory footprint, and much shorter startup/warmup times than a traditional Java application. You can basically get Go or C++ sized executables and memory footprints out of a Java application (it's pretty slick). As you mentioned, the only real difference is that you need to use a special compiler and you need to use the GraalVM runtime. The nasty part is that declarative code, usually annotations like those found in Retrofit, generally make use of runtime reflection. Runtime reflection messes with the ability of a native image builder at compile time, to determine every class that will be needed during runtime, simply because reflection allows for dynamic operations at runtime. There's a standard way to address this, where package authors basically provide some metadata with their library that indicates what classes might be needed at runtime, so that the native image compiler knows to include them at build time, but a lot of older libraries haven't gotten around to providing that. The old OKHttp clients and Retrofit, I've found, have not, and I doubt they ever will. I would offer to do the leg work for you to swap out the client but I'm much more familiar with Java than Kotlin, and I don't wanna mess with your API surface if people expect to be able to create an HTTP Client a certain way. If I get a little time, I'll see if I can be of some use! |
Ah, I was more asking so I can test/verify that whatever changes I made had the intended effects. Also, do you know if our library need to take any steps other than using a non-offending library (like special compiling/packaging steps), or would swapping it out be enough, and the rest is handled when you create your native image? |
Sorry, I get verbose sometimes. For your side of things I don't think you'd need to do anything other than swap it out. If you want an easy test bed for native images I can build you a starter project. I tend to use Quarkus but Micronaut and Spring have started promoting native images as well. |
A test bed project would be very helpful! |
Is your feature request related to a problem? Please describe.
I'd like to request the developers consider moving away from retrofit2. Retrofit2 does not play nicely with native compilation and development has slowed on the project significantly. Native compilation with GraalVM has the potential to save application developers upwards of 100MB of RAM per instance of their services, simply by natively compiling code at build time.
Describe the solution you'd like
Either moving away from a declarative HTTP client towards something like ktor or usage of a native capable declarative client like resteasy or feign.
Additional context
As additional context, I have a simple Java server application that uses the livekit server SDK. As a JVM application, the service uses 178MB of RAM in my Kubernetes environment. As a GraalVM native image (non-functional due to retrofit) that same service uses 26MB of RAM.
The text was updated successfully, but these errors were encountered: