-
Notifications
You must be signed in to change notification settings - Fork 245
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
jsii-ruby: low-level ruby client for jsii-runtime (#143)
Implement the low-level API for the jsii-ruby runtime client. This layer starts the jsii-runtime child node.js process and allows interacting it via the stdin/stdout request/response interface. Implemented as a leaky abstraction, so there is no need to implement glue in ruby for each kernel API. Sync overrides are implemented as well. Unit test verifies a common scenario, and specifically verifies synchronous and async virtual overrides. Added minimal "no op" support for ruby pacmak which simply emits the tarballs. This is needed for the initial set of tests. "npm run build" will: - Generate jsii-calc via pacmak (just tarballs for now) - "bundle install" gems - Run "robucop" (ruby linter) - Run "gem build" which builds the ruby gem - Runs unit tests Related to #144
- Loading branch information
Elad Ben-Israel
authored
Aug 6, 2018
1 parent
4e70209
commit ebdc6e8
Showing
12 changed files
with
411 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import * as spec from 'jsii-spec'; | ||
import { Generator } from '../generator'; | ||
import { Target, TargetOptions } from '../target'; | ||
|
||
export default class Ruby extends Target { | ||
protected readonly generator = new PackOnly(); | ||
|
||
constructor(options: TargetOptions) { | ||
super(options); | ||
} | ||
|
||
public build(sourceDir: string, outDir: string) { | ||
// TODO: "gem build" | ||
return this.copyFiles(sourceDir, outDir); | ||
} | ||
} | ||
|
||
// ################## | ||
// # CODE GENERATOR # | ||
// ################## | ||
|
||
class PackOnly extends Generator { | ||
|
||
protected getAssemblyOutputDir(_mod: spec.Assembly) { | ||
return '.'; | ||
} | ||
|
||
protected onBeginInterface(_ifc: spec.InterfaceType) { return; } | ||
protected onEndInterface(_ifc: spec.InterfaceType) { return; } | ||
protected onInterfaceMethod(_ifc: spec.InterfaceType, _method: spec.Method) { return; } | ||
protected onInterfaceMethodOverload(_ifc: spec.InterfaceType, _overload: spec.Method, _originalMethod: spec.Method) { return; } | ||
protected onInterfaceProperty(_ifc: spec.InterfaceType, _prop: spec.Property) { return; } | ||
protected onProperty(_cls: spec.ClassType, _prop: spec.Property) { return; } | ||
protected onStaticProperty(_cls: spec.ClassType, _prop: spec.Property) { return; } | ||
protected onUnionProperty(_cls: spec.ClassType, _prop: spec.Property, _union: spec.UnionTypeReference) { return; } | ||
protected onMethod(_cls: spec.ClassType, _method: spec.Method) { return; } | ||
protected onMethodOverload(_cls: spec.ClassType, _overload: spec.Method, _originalMethod: spec.Method) { return; } | ||
protected onStaticMethod(_cls: spec.ClassType, _method: spec.Method) { return; } | ||
protected onStaticMethodOverload(_cls: spec.ClassType, _overload: spec.Method, _originalMethod: spec.Method) { return; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
project/version.txt | ||
project/test/jsii-calc | ||
project/resources |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/bin/bash | ||
set -euo pipefail | ||
res="./project/resources" | ||
|
||
version=$(node -e "console.log(require('./package.json').version)") | ||
echo "${version}" > project/version.txt | ||
|
||
# embed jsii-runtime as a resource | ||
mkdir -p ${res} | ||
rsync -av node_modules/jsii-runtime/dist/ ${res} | ||
|
||
# generate jsii-calc for ruby | ||
mkdir -p project/test/jsii-calc | ||
jsii-pacmak -t ruby -o project/test/jsii-calc --recurse node_modules/jsii-calc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "jsii-ruby-runtime", | ||
"version": "0.5.0-beta", | ||
"description": "Ruby client for jsii runtime", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"scripts": { | ||
"gen": "/bin/bash generate.sh", | ||
"deps": "cd project && bundle install", | ||
"lint": "cd project && rubocop", | ||
"build": "npm run gen && npm run deps && npm run lint && cd project && gem build *.gemspec", | ||
"test": "cd project && ruby test/suite.rb" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^9.6.18", | ||
"jsii-calc": "^0.5.0-beta", | ||
"jsii-pacmak": "^0.5.0-beta", | ||
"jsii-runtime": "^0.5.0-beta", | ||
"typescript": "^2.9.2" | ||
}, | ||
"author": { | ||
"name": "Amazon Web Services", | ||
"url": "https://aws.amazon.com", | ||
"email": "aws-jsii@amazon.com" | ||
}, | ||
"license": "Apache-2.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/awslabs/jsii.git" | ||
}, | ||
"homepage": "https://github.com/awslabs/jsii" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Metrics/LineLength: | ||
Max: 200 | ||
|
||
Metrics/MethodLength: | ||
Max: 1000 | ||
|
||
Layout/IndentHash: | ||
EnforcedStyle: consistent | ||
|
||
Style/GuardClause: | ||
Enabled: false | ||
|
||
Style/IfUnlessModifier: | ||
Enabled: false | ||
|
||
Metrics/AbcSize: | ||
Enabled: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
source 'https://rubygems.org' | ||
|
||
gem 'rubocop', require: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
GEM | ||
remote: https://rubygems.org/ | ||
specs: | ||
ast (2.4.0) | ||
jaro_winkler (1.5.1) | ||
parallel (1.12.1) | ||
parser (2.5.1.2) | ||
ast (~> 2.4.0) | ||
powerpack (0.1.2) | ||
rainbow (3.0.0) | ||
rubocop (0.58.2) | ||
jaro_winkler (~> 1.5.1) | ||
parallel (~> 1.10) | ||
parser (>= 2.5, != 2.5.1.1) | ||
powerpack (~> 0.1) | ||
rainbow (>= 2.2.2, < 4.0) | ||
ruby-progressbar (~> 1.7) | ||
unicode-display_width (~> 1.0, >= 1.0.1) | ||
ruby-progressbar (1.9.0) | ||
unicode-display_width (1.4.0) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
rubocop | ||
|
||
BUNDLED WITH | ||
1.16.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
require 'json' | ||
package_json_path = File.join(File.dirname(__FILE__), '..', 'package.json') | ||
pkg = JSON.parse(File.read(package_json_path)) | ||
|
||
Gem::Specification.new do |s| | ||
s.name = 'jsii_runtime' | ||
s.version = pkg['version'] | ||
s.licenses = pkg['license'] | ||
s.summary = pkg['description'] | ||
s.authors = pkg['author'] | ||
s.files = Dir['lib/**'] | ||
puts s.files | ||
s.require_paths = ['lib'] | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
require 'open3' | ||
require 'logger' | ||
require 'json' | ||
require_relative 'jsii_runtime/errors' | ||
|
||
module Aws | ||
module Jsii | ||
# Represents the jsii-runtime | ||
class Runtime | ||
def initialize(debug: false) | ||
@logger = Logger.new(STDERR) | ||
|
||
@debug = debug | ||
@logger.level = debug ? Logger::DEBUG : Logger::INFO | ||
|
||
runtime_js = File.join(File.dirname(__FILE__), '..', 'resources', 'jsii-runtime.js') | ||
@logger.debug("jsii-runtime at: #{runtime_js}") | ||
env = {} | ||
env['JSII_DEBUG'] = '1' if @debug | ||
@stdin, @stdout, wait_thr = Open3.popen2(env, 'node', runtime_js) | ||
|
||
@logger.debug("jsii-runtime started on pid #{wait_thr.pid}") | ||
|
||
# ensure version compat. | ||
handshake | ||
|
||
at_exit { close } | ||
end | ||
|
||
def close | ||
@logger.debug('closing jsii-runtime child-process streams...') | ||
@stdin.close | ||
@stdout.close | ||
end | ||
|
||
def self.define_api(api) | ||
define_method(api) do |**opts| | ||
request_response(api: api, **opts) | ||
end | ||
end | ||
|
||
define_api(:load) | ||
define_api(:create) | ||
define_api(:del) | ||
define_api(:get) | ||
define_api(:sget) | ||
define_api(:set) | ||
define_api(:sset) | ||
define_api(:invoke) | ||
define_api(:sinvoke) | ||
define_api(:begin) | ||
define_api(:end) | ||
define_api(:callbacks) | ||
define_api(:complete) | ||
define_api(:naming) | ||
define_api(:stats) | ||
|
||
def on_callback(&blk) | ||
@callback_handler = blk | ||
end | ||
|
||
private | ||
|
||
def request_response(req) | ||
req_s = JSON.generate(req.delete_if { |_, v| v.nil? }) | ||
|
||
@logger.debug("> #{req_s}") | ||
@stdin.puts(req_s) | ||
|
||
resp = read_next_response | ||
@logger.debug("< #{JSON.generate(resp)}") | ||
|
||
return process_error(resp) if resp['error'] | ||
return process_callback(resp) if resp['callback'] | ||
|
||
# nil "ok" means undefined result (or void). | ||
resp['ok'] | ||
end | ||
|
||
def read_next_response | ||
line = @stdout.readline | ||
@logger.debug("line: #{line}") | ||
JSON.parse(line) | ||
end | ||
|
||
def handshake | ||
hello = read_next_response | ||
version = hello['hello'] | ||
|
||
expected_version = File.read(File.join(File.dirname(__FILE__), '..', 'version.txt')).strip | ||
expected_version_string = "jsii-runtime@#{expected_version}" | ||
|
||
if version != expected_version_string | ||
raise JsiiError, "Invalid jsii-runtime handshake version '#{version}'. Expected: '#{expected_version_string}'" | ||
end | ||
end | ||
|
||
def process_error(resp) | ||
message = resp['error'] | ||
stack = resp['stack'] | ||
message += "\n" + stack unless stack.nil? | ||
raise JsiiError, message | ||
end | ||
|
||
def process_callback(resp) | ||
raise JsiiError, 'no callback handler registered with on_callback' if @callback_handler.nil? | ||
callback = resp['callback'] | ||
|
||
result = nil | ||
err = nil | ||
|
||
begin | ||
result = @callback_handler.call(callback) | ||
rescue StandardError => e | ||
err = e | ||
end | ||
|
||
request_response(complete: { | ||
cbid: callback['cbid'], | ||
err: err, | ||
result: result | ||
}) | ||
end | ||
end | ||
end | ||
end |
6 changes: 6 additions & 0 deletions
6
packages/jsii-ruby-runtime/project/lib/jsii_runtime/errors.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module Aws | ||
module Jsii | ||
class JsiiError < StandardError | ||
end | ||
end | ||
end |
Oops, something went wrong.