From 1e1fe2f584734d011580fcd7558b52886ef84c9d Mon Sep 17 00:00:00 2001 From: Nerbyk Date: Sat, 10 Jun 2023 16:17:50 +0700 Subject: [PATCH 1/2] Add infra code for new ruby battle lambdas --- lib/resources/lambdas.ts | 70 ++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/lib/resources/lambdas.ts b/lib/resources/lambdas.ts index 56150d7..dca2341 100644 --- a/lib/resources/lambdas.ts +++ b/lib/resources/lambdas.ts @@ -5,22 +5,55 @@ import { RetentionDays } from "aws-cdk-lib/aws-logs"; import * as ssm from 'aws-cdk-lib/aws-ssm'; import { ITable } from "aws-cdk-lib/aws-dynamodb"; +enum OLangCase { + Ruby2_7 = 'ruby-2-7-x86', + Ruby3_2 = 'ruby-3-2-x86', + Ruby3_2_YJIT = 'ruby-3-2-yjit-x86' +}; + export interface LambdasProps extends StackProps { baseTable: ITable; } export type TLambdas = { - 'ruby-2.7-x86': IFunction + [OLangCase.Ruby2_7]: IFunction, + [OLangCase.Ruby3_2]: IFunction + [OLangCase.Ruby3_2_YJIT]: IFunction } type LambdaOptions = { - runtime: Runtime, - lpackage: string, - env?: { [key: string]: string } + runtime: Runtime; + lpackage: string; + env?: { + [key: string]: string; + } } export default class Lambdas extends Construct { - readonly Ruby2_7Lambda: Function; + public static readonly RUBY_LAMBDA_CONFIGS = { + [OLangCase.Ruby2_7]: { + runtime: Runtime.RUBY_2_7, + lpackage: 'ruby-2.7.zip', + env: { + GEM_PATH: './vendor' + } + }, + [OLangCase.Ruby3_2]: { + runtime: Runtime.RUBY_3_2, + lpackage: 'ruby-3.2.zip' + }, + [OLangCase.Ruby3_2_YJIT]: { + runtime: Runtime.RUBY_3_2, + lpackage: 'ruby-3.2.zip', + env: { + 'RUBY_YJIT_ENABLE': '1' + } + }, + } + + private Ruby2_7Lambda: Function; + private Ruby3_2Lambda: Function; + private Ruby3_2YJITLambda: Function; private props: LambdasProps; @@ -28,30 +61,33 @@ export default class Lambdas extends Construct { super(scope, id); this.props = props - this.Ruby2_7Lambda = this.createRubyLambda({ - runtime: Runtime.RUBY_2_7, lpackage: 'ruby-2.7.zip' - }); + + this.Ruby2_7Lambda = this.createRubyLambda(OLangCase.Ruby2_7) + this.Ruby3_2Lambda = this.createRubyLambda(OLangCase.Ruby3_2) + this.Ruby3_2YJITLambda = this.createRubyLambda(OLangCase.Ruby3_2_YJIT) } public all = (): TLambdas => ({ - 'ruby-2.7-x86': this.Ruby2_7Lambda + [OLangCase.Ruby2_7]: this.Ruby2_7Lambda, + [OLangCase.Ruby3_2]: this.Ruby3_2Lambda, + [OLangCase.Ruby3_2_YJIT]: this.Ruby3_2YJITLambda }) - private createRubyLambda(opts: LambdaOptions) { - const name = opts.lpackage.replace('.zip', '').replace(/\W/g, '_').toUpperCase() + private createRubyLambda(version: OLangCase) { + const config: LambdaOptions = Lambdas.RUBY_LAMBDA_CONFIGS[version] const lambdaProps = { - functionName: `${name}-Battle-Function`, - code: Code.fromAsset(`./packages/${opts.lpackage}`), + functionName: `${version}-Battle-Function`, + code: Code.fromAsset(`./packages/${config.lpackage}`), handler: 'src/func.handler', - runtime: opts.runtime, + runtime: config.runtime, environment: { - GEM_PATH: './vendor', - TABLE: this.props.baseTable.tableName + TABLE: this.props.baseTable.tableName, + ...(config.env || {}) } } - const rubyFunction = new Function(this, `${name}-lambda`, lambdaProps); + const rubyFunction = new Function(this, `${version}-lambda`, lambdaProps); this.props.baseTable.grantReadWriteData(rubyFunction); From 97ef43ef0c20865d4be4c102654556c64f68a7d1 Mon Sep 17 00:00:00 2001 From: Nerbyk Date: Sat, 10 Jun 2023 16:39:47 +0700 Subject: [PATCH 2/2] Add ruby 3.2 battle lambda --- .gitignore | 3 ++- lambdas/ruby-3.2/.bundle/config | 2 ++ lambdas/ruby-3.2/Gemfile | 5 +++++ lambdas/ruby-3.2/Gemfile.lock | 25 +++++++++++++++++++++ lambdas/ruby-3.2/src/func.rb | 40 +++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 lambdas/ruby-3.2/.bundle/config create mode 100644 lambdas/ruby-3.2/Gemfile create mode 100644 lambdas/ruby-3.2/Gemfile.lock create mode 100644 lambdas/ruby-3.2/src/func.rb diff --git a/.gitignore b/.gitignore index c0465f8..c0cab1d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ node_modules .cdk.staging cdk.out -packages \ No newline at end of file +packages +vendor \ No newline at end of file diff --git a/lambdas/ruby-3.2/.bundle/config b/lambdas/ruby-3.2/.bundle/config new file mode 100644 index 0000000..8fb682c --- /dev/null +++ b/lambdas/ruby-3.2/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_PATH: "vendor/bundle " diff --git a/lambdas/ruby-3.2/Gemfile b/lambdas/ruby-3.2/Gemfile new file mode 100644 index 0000000..c7402e7 --- /dev/null +++ b/lambdas/ruby-3.2/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem 'aws-sdk-dynamodb', '~> 1' diff --git a/lambdas/ruby-3.2/Gemfile.lock b/lambdas/ruby-3.2/Gemfile.lock new file mode 100644 index 0000000..39ebbb4 --- /dev/null +++ b/lambdas/ruby-3.2/Gemfile.lock @@ -0,0 +1,25 @@ +GEM + remote: https://rubygems.org/ + specs: + aws-eventstream (1.2.0) + aws-partitions (1.777.0) + aws-sdk-core (3.174.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) + jmespath (~> 1, >= 1.6.1) + aws-sdk-dynamodb (1.85.0) + aws-sdk-core (~> 3, >= 3.174.0) + aws-sigv4 (~> 1.1) + aws-sigv4 (1.5.2) + aws-eventstream (~> 1, >= 1.0.2) + jmespath (1.6.2) + +PLATFORMS + x86_64-darwin-22 + +DEPENDENCIES + aws-sdk-dynamodb (~> 1) + +BUNDLED WITH + 2.4.10 diff --git a/lambdas/ruby-3.2/src/func.rb b/lambdas/ruby-3.2/src/func.rb new file mode 100644 index 0000000..d5362f5 --- /dev/null +++ b/lambdas/ruby-3.2/src/func.rb @@ -0,0 +1,40 @@ +require "aws-sdk-dynamodb" +require "json" + +DB = ::Aws::DynamoDB::Client.new +LANG_REGEXP = /^\/ruby-(\d)-(\d)-(yjit-)?(x86|arm)$/ + +Item = Data.define(:langCase, :iteration, :raw_event, :event_params) do + def initialize(langCase:, iteration:, raw_event: nil, event_params: {}) = super + def to_h = super.compact.except(:event_params).merge(**event_params) +end + +def handler(event:, **) + event = JSON.parse(event.to_json, symbolize_names: true) + lang = event[:path].gsub(/\//, '') + event_params = parse_event_body_params(event) => 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: item.to_h, + return_values: "ALL_OLD" + ).attributes + + previous_item = DB.get_item( + table_name: ENV["TABLE"], + key: Item.new(lang, iteration - 1).to_h + ).item + + { statusCode: 200, body: (previous_item || new_item).to_json } +end + +def parse_event_body_params(event) = case event + in isBase64Encoded: encoded, body: body, path: LANG_REGEXP + b = encoded ? Base64.decode64(body) : body + + JSON.parse(b, symbolize_names: true) + end