Using GraalVM to Run Native Java in AWS Lambda with Golang
engineering.opsgenie.com
engineering.opsgenie.com
What would really be neat is to leverage Graal's polyglot iface a bit higher. I am not sure the status of llgo these days, but compile Go to LLVM bitcode and then leverage that from Java and compile to a single binary. Or even expose Go's awesome stdlib to JVM developers that way. But the practicality of doing some of these things becomes a bit lost beyond toy use.
Keeping on the non-practical, fun note, I wrote a transpiler in the other direction[0]. It compiles Java bytecode to Go code. It works decently actually but I stopped work on it because my approach strains the Go compiler too much[1]. I even started emulating some of the base Java calls as Go calls, but that became tedious too.
0 - https://github.com/cretz/goahead 1 - https://github.com/golang/go/issues/18602
but this is probably a little less riskier because i'm sure if AWS made a change to the go protocol they would test it against their existing go libraries they have published but they can't test it against your <insert language> implementation.
Most languages that satisfy this criteria can also speak the C ABI. So why not write a native module for Node, Python or Java? Dealing with those interfaces is faster and they're better standardized.
FWIW.../me is running Rust on lambda as a Node native module.
Is there anything about the way the Go runtime works that makes it fundamentally better than the Python runtime's semantics? Is the entirety of it that you really don't need to do a lot of work but Go is going to be marginally faster at doing that tiny bit of work (dlopen and ferry bytes across)? I think the underlying serialization format in Python is JSON. I have no idea how fast Gob is.
Any idea how much you lose on the FFI bridge? (My understanding is you need to copy the Go struct you get out before you can pass it to FFI. I'm very familiar with FFI in general and especially on the JVM, but only superficially with Go's in particular.)
Despite that, e.g. the Python runtime implements RPCs by sharing a memory segment with the host process running outside the container, which seems like massive overkill to me.
I played with writing a library that would exec a new binary over the top of Python (for fun), but doing so loses access to the segment. There doesn't seem to be any UNIX API that would allow access to it to be recovered across exec. It might be possible by leaving the Python process idle and mmapping from /proc/parent_pid/mem in a child, but that requires debugging privileges almost certainly absent in a container.
The segment is created by mmapping a passed FD, which is then closed by the bootstrap code. I couldn't find any mechanism for moving that segment across processes, or inheriting it across exec.
So much simpler if they just implemented HTTP over a socket or suchlike
To be honest, I think most people would (if you ask them) assume a carburetor is a part of a typical car, even though fuel injectors have been commonplace for decades now.
Most people just don't think about how cars work.
https://www.washingtonpost.com/news/wonk/wp/2014/12/29/the-b...
You often cannot see because of frost on the inside of the windshield. Save a few drops of gas and have to replace a whole car (due to a crash) is a weak strategy.
Cars from the 80's only needed to warm up if you lived in the upper Midwest, or when they got old and started falling apart.
If you were a kid in the 80's or 90's and your neighborhood wasn't well off you might be forgiven for thinking all cars had this problem, because everyone drove used cars until they fell apart.
[Edit] Looks like OP is going to a University in Turkey. The possibility of cultural disconnects with SV and PNW is not surprising at all.
Then you'd have Python code executed by an interpreter written in Java compiled by Graal to produce a native binary which will be registered on AWS as a Go executable and will communicate via Go's net/rpc.
... as opposed to switching the runtime to Python ;-)
I smiled. But a more plausible Markov-chain headline might be "Using GraalVM to Run Native Java with Rust, Machine Learning, and the Gut Microbiome".
Maybe I'm crazy, but I much prefer to keep things as simple as possible. Pick a technology stack and use just it. Don't play mix and match games.
If java is just not working for you in lambda, due to the startup cost, is it time to consider that Java might not be the right technology at all for you to be using there?
If you're determined to stick with lambda, maybe it's time to bite-the-bullet and use Go (or something else with fast startup times).
If you're determined to stick with Java, maybe it's time to consider that maybe Lambda isn't the right solution for you? How much benefit are you really seeing vs the engineering cost and complications?