From 453332b0701c31bbdc4e2d0d49c626346ee4e268 Mon Sep 17 00:00:00 2001 From: Nerbyk Date: Fri, 9 Jun 2023 16:08:00 +0700 Subject: [PATCH 1/3] Introduce YJIT ruby 3.2 Lambda --- main.tf | 9 +++- ruby-yjit-3.2/main.tf | 94 +++++++++++++++++++++++++++++++++++++++ ruby-yjit-3.2/src/func.rb | 30 +++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 ruby-yjit-3.2/main.tf create mode 100644 ruby-yjit-3.2/src/func.rb diff --git a/main.tf b/main.tf index d18e6b2..7371fd5 100644 --- a/main.tf +++ b/main.tf @@ -59,6 +59,12 @@ module "ruby-2_7-lambda" { depends_on = [aws_dynamodb_table.data] } +module "ruby-yjit-3_2-lambda" { + source = "./ruby-yjit-3.2" + data_table = aws_dynamodb_table.data + depends_on = [aws_dynamodb_table.data] +} + resource "aws_apigatewayv2_api" "gateway" { name = "lambda-battle-api" protocol_type = "HTTP" @@ -66,7 +72,8 @@ resource "aws_apigatewayv2_api" "gateway" { locals { lambda_resources = { - "ruby-2_7-x86" = { "module" = module.ruby-2_7-lambda } + "ruby-2_7-x86" = { "module" = module.ruby-2_7-lambda }, + "ruby-yjit-3_2-x86" = { "module" = module.ruby-yjit-3_2-lambda } } } diff --git a/ruby-yjit-3.2/main.tf b/ruby-yjit-3.2/main.tf new file mode 100644 index 0000000..a8770f7 --- /dev/null +++ b/ruby-yjit-3.2/main.tf @@ -0,0 +1,94 @@ +variable "data_table" {} + +resource "aws_iam_role" "lambda_role" { + name = "ruby-yjit-3.2_lambda_role" + assume_role_policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Action" : "sts:AssumeRole", + "Principal" : { + "Service" : "lambda.amazonaws.com" + }, + "Effect" : "Allow", + "Sid" : "" + } + ] + }) +} + +resource "aws_iam_policy" "lambda_policy" { + name = "ruby-yjit-3.2_battle_lambda_role" + path = "/" + description = "AWS IAM Policy for ruby yjit 3.2 lambda" + + policy = jsonencode({ + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": "arn:aws:logs:*:*:*", + "Effect": "Allow" + }, + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:GetItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:BatchWriteItem", + "dynamodb:PutItem", + "dynamodb:UpdateItem" + ], + "Resource": var.data_table.arn, + "Effect": "Allow" + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role" { + role = aws_iam_role.lambda_role.name + policy_arn = aws_iam_policy.lambda_policy.arn +} + +locals { + dist_path = "${path.module}/dist/lambda.zip" +} + +data "archive_file" "source" { + type = "zip" + source_dir = "${path.module}/src" + output_path = local.dist_path +} + +resource "aws_lambda_function" "lambda" { + filename = local.dist_path + function_name = "ruby-yjit-3_2_lambda" + role = aws_iam_role.lambda_role.arn + handler = "func.handler" + + source_code_hash = data.archive_file.source.output_base64sha256 + environment { + variables = { + "GEM_PATH" = "./vendor", + "TABLE" = var.data_table.name, + "RUBY_YJIT_ENABLE" = 1 + } + } + + runtime = "ruby3.2" + memory_size = 128 + timeout = 16 + #reserved_concurrent_executions = 1 + + depends_on = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role] +} + +output "lambda" { + value = aws_lambda_function.lambda +} diff --git a/ruby-yjit-3.2/src/func.rb b/ruby-yjit-3.2/src/func.rb new file mode 100644 index 0000000..fc7b6ae --- /dev/null +++ b/ruby-yjit-3.2/src/func.rb @@ -0,0 +1,30 @@ +require "aws-sdk-dynamodb" + +DB = ::Aws::DynamoDB::Client.new +LANG = "ruby-yjit-3.2-x86" + +def handler(event:, context:) + return { statusCode: 400, body: "yjit not enabled"} unless RubyVM::YJIT.enabled? + + event_params = parse_event_body_params(event) + iteration = event_params["iteration"] + + return { statusCode: 400 } unless iteration + + new_item = DB.put_item( + table_name: ENV["TABLE"], + item: { **event_params, + "langCase" => LANG, + "iteration" => iteration, + "raw_event" => event.to_h + }, + return_values: "ALL_OLD").attributes + + previous_item = DB.get_item(table_name: ENV["TABLE"], key: { langCase: LANG, iteration: iteration - 1 }).item + + { statusCode: 200, body: (previous_item || new_item).to_json } +end + +def parse_event_body_params(event) + JSON.parse(event["isBase64Encoded"] ? Base64.decode64(event["body"]) : event["body"]) +end From 97847da13d8a58aff7c8e2a514ab22ea1126d709 Mon Sep 17 00:00:00 2001 From: Nerbyk Date: Fri, 9 Jun 2023 17:00:24 +0700 Subject: [PATCH 2/3] add some ruby 3.2 features --- ruby-yjit-3.2/src/func.rb | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/ruby-yjit-3.2/src/func.rb b/ruby-yjit-3.2/src/func.rb index fc7b6ae..76f9993 100644 --- a/ruby-yjit-3.2/src/func.rb +++ b/ruby-yjit-3.2/src/func.rb @@ -2,29 +2,32 @@ DB = ::Aws::DynamoDB::Client.new LANG = "ruby-yjit-3.2-x86" +ITEM = Data.define(:langCase, :iteration, :raw_event, :event_params) do + def to_h = super.except(:event_params).merge(**event_params) +end -def handler(event:, context:) +def handler(event:, **) return { statusCode: 400, body: "yjit not enabled"} unless RubyVM::YJIT.enabled? - + event_params = parse_event_body_params(event) - iteration = event_params["iteration"] + event_params => iteration: return { statusCode: 400 } unless iteration + + item = ITEM.new(LANG, iteration, event.to_h, event_params) new_item = DB.put_item( - table_name: ENV["TABLE"], - item: { **event_params, - "langCase" => LANG, - "iteration" => iteration, - "raw_event" => event.to_h - }, - return_values: "ALL_OLD").attributes + table_name: ENV["TABLE"], + item: item.to_h, + return_values: "ALL_OLD" + ).attributes previous_item = DB.get_item(table_name: ENV["TABLE"], key: { langCase: LANG, iteration: iteration - 1 }).item { statusCode: 200, body: (previous_item || new_item).to_json } end -def parse_event_body_params(event) - JSON.parse(event["isBase64Encoded"] ? Base64.decode64(event["body"]) : event["body"]) -end +def parse_event_body_params(event) = JSON.parse( + (event in isBase64Encoded: TrueClass, body: body) ? Base64.decode64(body) : body, + symbolize_names: true +) From 1bd4777d51bbea6ce86e82ca95f793300e42de0a Mon Sep 17 00:00:00 2001 From: Nerbyk Date: Fri, 9 Jun 2023 18:08:35 +0700 Subject: [PATCH 3/3] ITEM => Item --- ruby-yjit-3.2/src/func.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ruby-yjit-3.2/src/func.rb b/ruby-yjit-3.2/src/func.rb index 76f9993..76cab03 100644 --- a/ruby-yjit-3.2/src/func.rb +++ b/ruby-yjit-3.2/src/func.rb @@ -2,7 +2,8 @@ DB = ::Aws::DynamoDB::Client.new LANG = "ruby-yjit-3.2-x86" -ITEM = Data.define(:langCase, :iteration, :raw_event, :event_params) do + +Item = Data.define(:langCase, :iteration, :raw_event, :event_params) do def to_h = super.except(:event_params).merge(**event_params) end @@ -14,7 +15,7 @@ def handler(event:, **) return { statusCode: 400 } unless iteration - item = ITEM.new(LANG, iteration, event.to_h, event_params) + item = Item.new(LANG, iteration, event.to_h, event_params) new_item = DB.put_item( table_name: ENV["TABLE"],