Official AWS Ruby Support for Jets
Official AWS Ruby Support for Jets ๊ด๋ จ
Ever since AWS released official Ruby support for AWS Lambda on Nov 29 at re:Invent, Iโve been super excited about switching Jets over to the official AWS version of Ruby. Happy to say that Jets is now on the official AWS Ruby runtime. Knew it was going to be interesting to learn about AWS Lambda Custom Runtimes and Lambda Layers as part of this Jets update.
Lambda Custom Runtimes Are Fast
The official Lambda Ruby runtime is built on top of AWS Lambda Custom Runtimes technology. Custom Runtimes allow us to add support of any language. Since Ruby is now officially supported, we do not have to create our own runtime. Though there are use-cases for this. For example, different Ruby versions.
It was fun to study and compare how Custom Runtimes work vs a traditional shim. If you have ever built your own shim yourself to support other languages, they way AWS implemented Custom Runtimes would make complete sense.
Essentially, a Custom Runtime is a custom server. The server proxies request from one language to another. This ensures that the runtime is kept in memory and fast. This is similar to how Jets achieved Native performance for Ruby before official support.
The beautiful thing about official Custom Runtimes is that the runtime gets prepackaged as part of the Lambda function creation process. Very cool!
Lambda Custom Runtime Fix
Thereโs an additional benefit of AWS implementing Ruby support as a Custom Runtime. When updating Jets, I ran into an issue with the actual AWS Ruby Runtime itself. The Ruby aws-sdk
has itโs own version of .to_json
that collides with the ActiveSupport version. The issue only seems to trigger on some aws-sdk calls like sns.publish
. The cool thing about Ruby being implemented as Custom Runtime is that we can patch a fix for it now. We do not have to wait until AWS officially fixes it. Hereโs the fix for the .to_json
collision in Jets: lambda/marshaller.rb.
Lambda Layers: Gem Layers
AWS introduced Lambda Layers at the same time as Ruby Support. With Lambda Layers, you can add additional files to the Lambda server in the form of layers. These layers are combined together like a pancake and flattened out. From the Lambda Layers docs, AWS suggests:
With layers, you can use libraries in your function without needing to include them in your deployment package.
This helps you to keep the code package size under the key 3MB limit, thereby allowing you to use the live Lambda console code editor.
You can develop your function code in the Lambda console as long as you keep your deployment package under 3 MB.
Having the ability to change your code and debug live significantly increases your development speed and happiness. Previously, Jets accomplished this by separately packaging the dependencies and lazying loading them as part of the shim. In this Jets upgrade, that logic has all be converted to a Lambda Layer and named the Gem Layer. Once again, awesome.
Screenshot
Hopefully, you found the background info above interesting.
Jets Code
For those who might not seen Jets code before, here are some examples. Hereโs a simple function:
app/functions/
simple.rb
:
def lambda_handler(event:, context:)
pp event
puts "hello world"
{foo: "bar"}
end
Hereโs a Jets Controller:
app/controllers/
posts_controller.rb
:
class PostsController < ApplicationController
def index
# renders Lambda Proxy structure compatiable with API Gateway
render json: {hello: "world", action: "index"}
end
def show
id = params[:id] # params available
# puts goes to the lambda logs
puts event # raw lambda event available
render json: {action: "show", id: id}
end
end
Hereโs a Jets Job.
app/jobs/
hard_job.rb
:
class HardJob < ApplicationJob
class_timeout 300 # 300s or 5m, current Lambda max is 15m
rate "10 hours" # every 10 hours
def dig
puts "done digging"
end
cron "0 */12 * * ? *" # every 12 hours
def lift
puts "done lifting"
end
end
More info on the official rubyonjets.com docs.
How to upgrade
The upgrade path is transparent. Since Jets Controllers and Jobs interfaces did not change, thereโs not a lot to it:
cd project # your jets project
bundle update
jets upgrade # optional
jets deploy
The jets upgrade
command is actually optional and simply gets rid of a deprecation warning for a config removal in the latest version.
Thatโs it! Jets is now on official AWS Ruby Support. Hope you like this article and give Jets a try. Also if you find Jets interesting, please give it โญ๏ธ it on tongueroo/jets
. Iโd appreciate it. ๐
Live demos
Here are some additional Live Demos of Jets applications:
- A Simple API with Jets: A Simple API. Hereโs a the blog post: Build an API with the Jets Ruby Serverless Framework
- Jets Afterburner: Rails Support: Please read over the considerations in the docs.
- Mega Mode: Jets and Rails Combined: A interesting hybrid mode.
- Image Upload with CarrierWave: Binary Support
More examples are in the tongueroo/jets-examples
repo.
Binary Gems
Ruby serverless applications might also use native binary gems. Jets uses Lambda Gems to make for a seamless and much easier deploy process. Lambda Gems is currently in beta, and early signups will receive a special offer for their support.