itsi 0.2.16 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Cargo.lock +4 -2
- data/crates/itsi_acme/Cargo.toml +1 -1
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_server/Cargo.toml +3 -1
- data/crates/itsi_server/src/lib.rs +6 -1
- data/crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +2 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_call.rs +4 -4
- data/crates/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +14 -13
- data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +64 -33
- data/crates/itsi_server/src/ruby_types/itsi_http_response.rs +151 -152
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +6 -15
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +26 -5
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +1 -1
- data/crates/itsi_server/src/server/binds/listener.rs +45 -7
- data/crates/itsi_server/src/server/frame_stream.rs +142 -0
- data/crates/itsi_server/src/server/http_message_types.rs +142 -9
- data/crates/itsi_server/src/server/io_stream.rs +28 -5
- data/crates/itsi_server/src/server/lifecycle_event.rs +1 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +8 -10
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +3 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +54 -56
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +5 -7
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +5 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +7 -10
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +1 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +4 -6
- data/crates/itsi_server/src/server/mod.rs +1 -0
- data/crates/itsi_server/src/server/process_worker.rs +3 -4
- data/crates/itsi_server/src/server/serve_strategy/acceptor.rs +16 -12
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +87 -31
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +158 -142
- data/crates/itsi_server/src/server/signal.rs +37 -9
- data/crates/itsi_server/src/server/thread_worker.rs +84 -69
- data/crates/itsi_server/src/services/itsi_http_service.rs +43 -43
- data/crates/itsi_server/src/services/static_file_server.rs +28 -47
- data/docs/benchmark-dashboard/.gitignore +27 -0
- data/docs/benchmark-dashboard/app/api/benchmarks/route.ts +22 -0
- data/docs/benchmark-dashboard/app/globals.css +94 -0
- data/docs/benchmark-dashboard/app/layout.tsx +20 -0
- data/docs/benchmark-dashboard/app/page.tsx +252 -0
- data/docs/benchmark-dashboard/components/benchmark-dashboard.tsx +1663 -0
- data/docs/benchmark-dashboard/components/theme-provider.tsx +11 -0
- data/docs/benchmark-dashboard/components/ui/accordion.tsx +58 -0
- data/docs/benchmark-dashboard/components/ui/alert-dialog.tsx +141 -0
- data/docs/benchmark-dashboard/components/ui/alert.tsx +59 -0
- data/docs/benchmark-dashboard/components/ui/aspect-ratio.tsx +7 -0
- data/docs/benchmark-dashboard/components/ui/avatar.tsx +50 -0
- data/docs/benchmark-dashboard/components/ui/badge.tsx +36 -0
- data/docs/benchmark-dashboard/components/ui/breadcrumb.tsx +115 -0
- data/docs/benchmark-dashboard/components/ui/button.tsx +56 -0
- data/docs/benchmark-dashboard/components/ui/calendar.tsx +66 -0
- data/docs/benchmark-dashboard/components/ui/card.tsx +79 -0
- data/docs/benchmark-dashboard/components/ui/carousel.tsx +262 -0
- data/docs/benchmark-dashboard/components/ui/chart.tsx +365 -0
- data/docs/benchmark-dashboard/components/ui/checkbox.tsx +30 -0
- data/docs/benchmark-dashboard/components/ui/collapsible.tsx +11 -0
- data/docs/benchmark-dashboard/components/ui/command.tsx +153 -0
- data/docs/benchmark-dashboard/components/ui/context-menu.tsx +200 -0
- data/docs/benchmark-dashboard/components/ui/dialog.tsx +122 -0
- data/docs/benchmark-dashboard/components/ui/drawer.tsx +118 -0
- data/docs/benchmark-dashboard/components/ui/dropdown-menu.tsx +200 -0
- data/docs/benchmark-dashboard/components/ui/form.tsx +178 -0
- data/docs/benchmark-dashboard/components/ui/hover-card.tsx +29 -0
- data/docs/benchmark-dashboard/components/ui/input-otp.tsx +71 -0
- data/docs/benchmark-dashboard/components/ui/input.tsx +22 -0
- data/docs/benchmark-dashboard/components/ui/label.tsx +26 -0
- data/docs/benchmark-dashboard/components/ui/loading-spinner.tsx +12 -0
- data/docs/benchmark-dashboard/components/ui/menubar.tsx +236 -0
- data/docs/benchmark-dashboard/components/ui/navigation-menu.tsx +128 -0
- data/docs/benchmark-dashboard/components/ui/pagination.tsx +117 -0
- data/docs/benchmark-dashboard/components/ui/popover.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/progress.tsx +28 -0
- data/docs/benchmark-dashboard/components/ui/radio-group.tsx +44 -0
- data/docs/benchmark-dashboard/components/ui/resizable.tsx +45 -0
- data/docs/benchmark-dashboard/components/ui/scroll-area.tsx +48 -0
- data/docs/benchmark-dashboard/components/ui/select.tsx +160 -0
- data/docs/benchmark-dashboard/components/ui/separator.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/sheet.tsx +140 -0
- data/docs/benchmark-dashboard/components/ui/sidebar.tsx +763 -0
- data/docs/benchmark-dashboard/components/ui/skeleton.tsx +15 -0
- data/docs/benchmark-dashboard/components/ui/slider.tsx +28 -0
- data/docs/benchmark-dashboard/components/ui/sonner.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/switch.tsx +29 -0
- data/docs/benchmark-dashboard/components/ui/table.tsx +117 -0
- data/docs/benchmark-dashboard/components/ui/tabs.tsx +55 -0
- data/docs/benchmark-dashboard/components/ui/textarea.tsx +22 -0
- data/docs/benchmark-dashboard/components/ui/toast.tsx +129 -0
- data/docs/benchmark-dashboard/components/ui/toaster.tsx +35 -0
- data/docs/benchmark-dashboard/components/ui/toggle-group.tsx +61 -0
- data/docs/benchmark-dashboard/components/ui/toggle.tsx +45 -0
- data/docs/benchmark-dashboard/components/ui/tooltip.tsx +30 -0
- data/docs/benchmark-dashboard/components/ui/use-mobile.tsx +19 -0
- data/docs/benchmark-dashboard/components/ui/use-toast.ts +194 -0
- data/docs/benchmark-dashboard/components.json +21 -0
- data/docs/benchmark-dashboard/dist/benchmark-dashboard.css +1 -0
- data/docs/benchmark-dashboard/dist/benchmark-dashboard.iife.js +211 -0
- data/docs/benchmark-dashboard/dist/placeholder-logo.png +0 -0
- data/docs/benchmark-dashboard/dist/placeholder-logo.svg +1 -0
- data/docs/benchmark-dashboard/dist/placeholder-user.jpg +0 -0
- data/docs/benchmark-dashboard/dist/placeholder.jpg +0 -0
- data/docs/benchmark-dashboard/dist/placeholder.svg +1 -0
- data/docs/benchmark-dashboard/embed.tsx +13 -0
- data/docs/benchmark-dashboard/hooks/use-mobile.tsx +19 -0
- data/docs/benchmark-dashboard/hooks/use-toast.ts +194 -0
- data/docs/benchmark-dashboard/lib/benchmark-utils.ts +54 -0
- data/docs/benchmark-dashboard/lib/utils.ts +6 -0
- data/docs/benchmark-dashboard/next.config.mjs +14 -0
- data/docs/benchmark-dashboard/package-lock.json +5859 -0
- data/docs/benchmark-dashboard/package.json +72 -0
- data/docs/benchmark-dashboard/pnpm-lock.yaml +5 -0
- data/docs/benchmark-dashboard/postcss.config.mjs +8 -0
- data/docs/benchmark-dashboard/styles/globals.css +94 -0
- data/docs/benchmark-dashboard/tailwind.config.ts +96 -0
- data/docs/benchmark-dashboard/tsconfig.json +27 -0
- data/docs/benchmark-dashboard/vite.config.ts +24 -0
- data/docs/build.rb +52 -0
- data/docs/content/benchmarks/index.md +96 -0
- data/docs/content/getting_started/_index.md +76 -46
- data/docs/hugo.yaml +3 -0
- data/docs/static/results.json +1 -0
- data/docs/static/scripts/benchmark-dashboard.iife.js +211 -0
- data/docs/static/styles/benchmark-dashboard.css +1 -0
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/server/Cargo.lock +3 -1
- data/gems/server/exe/itsi +6 -1
- data/gems/server/lib/itsi/http_request.rb +31 -39
- data/gems/server/lib/itsi/http_response.rb +5 -0
- data/gems/server/lib/itsi/rack_env_pool.rb +59 -0
- data/gems/server/lib/itsi/server/config/dsl.rb +5 -4
- data/gems/server/lib/itsi/server/config/middleware/proxy.rb +1 -1
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +2 -2
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +6 -2
- data/gems/server/lib/itsi/server/config/options/include.rb +5 -2
- data/gems/server/lib/itsi/server/config/options/pipeline_flush.md +16 -0
- data/gems/server/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/writev.md +25 -0
- data/gems/server/lib/itsi/server/config/options/writev.rb +19 -0
- data/gems/server/lib/itsi/server/config.rb +21 -8
- data/gems/server/lib/itsi/server/default_config/Itsi.rb +1 -4
- data/gems/server/lib/itsi/server/grpc/grpc_call.rb +2 -0
- data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +2 -2
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -1
- data/gems/server/lib/itsi/server/rack_interface.rb +17 -12
- data/gems/server/lib/itsi/server/scheduler_interface.rb +2 -0
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +1 -0
- data/gems/server/lib/ruby_lsp/itsi/addon.rb +12 -13
- data/gems/server/test/helpers/test_helper.rb +12 -13
- data/gems/server/test/middleware/grpc/grpc.rb +13 -14
- data/gems/server/test/middleware/grpc/test_service_impl.rb +3 -3
- data/gems/server/test/middleware/proxy.rb +262 -268
- data/lib/itsi/version.rb +1 -1
- metadata +96 -6
- data/tasks.txt +0 -28
@@ -10,10 +10,7 @@ env = ENV.fetch("APP_ENV") { ENV.fetch("RACK_ENV", "development") }
|
|
10
10
|
|
11
11
|
# Number of worker processes to spawn
|
12
12
|
# If more than 1, Itsi will be booted in Cluster mode
|
13
|
-
workers ENV
|
14
|
-
require "etc"
|
15
|
-
env == "development" ? 1 : nil
|
16
|
-
}
|
13
|
+
workers ENV["ITSI_WORKERS"]&.to_i || env == "development" ? 1 : nil
|
17
14
|
|
18
15
|
# Number of threads to spawn per worker process
|
19
16
|
# For pure CPU bound applicationss, you'll get the best results keeping this number low
|
@@ -79,7 +79,7 @@ module Itsi
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def handle_client_streaming(active_call)
|
82
|
-
response = service.send(active_call.method_name, active_call
|
82
|
+
response = service.send(active_call.method_name, active_call)
|
83
83
|
active_call.remote_send(response)
|
84
84
|
end
|
85
85
|
|
@@ -94,7 +94,7 @@ module Itsi
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def handle_bidi_streaming(active_call)
|
97
|
-
result = service.send(active_call.method_name, active_call.
|
97
|
+
result = service.send(active_call.method_name, active_call.each, active_call) do |response|
|
98
98
|
active_call.remote_send(response)
|
99
99
|
end
|
100
100
|
return unless result.is_a?(Enumerator)
|
@@ -12,7 +12,7 @@ module Itsi
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
lambda do |request|
|
15
|
-
Server.respond(request, app.call(request.to_rack_env))
|
15
|
+
Server.respond(request, app.call(env = request.to_rack_env), env)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -20,14 +20,14 @@ module Itsi
|
|
20
20
|
# Here we build the env, and invoke the Rack app's call method.
|
21
21
|
# We then turn the Rack response into something Itsi server understands.
|
22
22
|
def call(app, request)
|
23
|
-
respond request, app.call(request.to_rack_env)
|
23
|
+
respond request, app.call(env = request.to_rack_env), env
|
24
24
|
end
|
25
25
|
|
26
26
|
# Itsi responses are asynchronous and can be streamed.
|
27
27
|
# Response chunks are sent using response.send_frame
|
28
28
|
# and the response is finished using response.close_write.
|
29
29
|
# If only a single chunk is written, you can use the #send_and_close method.
|
30
|
-
def respond(request, (status, headers, body))
|
30
|
+
def respond(request, (status, headers, body), env)
|
31
31
|
response = request.response
|
32
32
|
|
33
33
|
# Don't try and respond if we've been hijacked.
|
@@ -39,13 +39,16 @@ module Itsi
|
|
39
39
|
|
40
40
|
# 2. Set Headers
|
41
41
|
body_streamer = streaming_body?(body) ? body : headers.delete("rack.hijack")
|
42
|
-
|
43
|
-
|
42
|
+
|
43
|
+
response.reserve_headers(headers.size)
|
44
|
+
|
45
|
+
for key, value in headers
|
46
|
+
case value
|
47
|
+
when String then response[key] = value
|
48
|
+
when Array
|
44
49
|
value.each do |v|
|
45
50
|
response[key] = v
|
46
51
|
end
|
47
|
-
elsif value.is_a?(String)
|
48
|
-
response[key] = value
|
49
52
|
end
|
50
53
|
end
|
51
54
|
|
@@ -53,15 +56,15 @@ module Itsi
|
|
53
56
|
# As soon as we start setting the response
|
54
57
|
# the server will begin to stream it to the client.
|
55
58
|
|
56
|
-
# If we're partially hijacked or returned a streaming body,
|
57
|
-
# stream this response.
|
58
59
|
|
59
60
|
if body_streamer
|
61
|
+
# If we're partially hijacked or returned a streaming body,
|
62
|
+
# stream this response.
|
60
63
|
body_streamer.call(response)
|
61
64
|
|
62
|
-
# If we're enumerable with more than one chunk
|
63
|
-
# also stream, otherwise write in a single chunk
|
64
65
|
elsif body.respond_to?(:each) || body.respond_to?(:to_ary)
|
66
|
+
# If we're enumerable with more than one chunk
|
67
|
+
# also stream, otherwise write in a single chunk
|
65
68
|
unless body.respond_to?(:each)
|
66
69
|
body = body.to_ary
|
67
70
|
raise "Body #to_ary didn't return an array" unless body.is_a?(Array)
|
@@ -78,8 +81,10 @@ module Itsi
|
|
78
81
|
else
|
79
82
|
response.send_and_close(body.to_s)
|
80
83
|
end
|
84
|
+
rescue EOFError
|
85
|
+
response.close
|
81
86
|
ensure
|
82
|
-
|
87
|
+
RackEnvPool.checkin(env)
|
83
88
|
body.close if body.respond_to?(:close)
|
84
89
|
end
|
85
90
|
|
@@ -12,6 +12,7 @@ require_relative "server/rack/handler/itsi"
|
|
12
12
|
require_relative "server/config"
|
13
13
|
require_relative "server/typed_handlers"
|
14
14
|
require_relative "standard_headers"
|
15
|
+
require_relative "rack_env_pool"
|
15
16
|
require_relative "http_request"
|
16
17
|
require_relative "http_response"
|
17
18
|
require_relative "passfile"
|
@@ -5,8 +5,8 @@ require "itsi/server"
|
|
5
5
|
|
6
6
|
module RubyLsp
|
7
7
|
module Itsi
|
8
|
-
class Addon < ::RubyLsp::Addon
|
9
|
-
def activate(
|
8
|
+
class Addon < ::RubyLsp::Addon # rubocop:disable Style/Documentation
|
9
|
+
def activate(_global_state, message_queue)
|
10
10
|
@message_queue = message_queue
|
11
11
|
end
|
12
12
|
|
@@ -20,33 +20,34 @@ module RubyLsp
|
|
20
20
|
"0.1.0"
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
23
|
def create_completion_listener(response_builder, node_context, dispatcher, uri)
|
25
|
-
return unless uri.to_s.
|
24
|
+
return unless uri.to_s =~ /itsi.rb$/i
|
25
|
+
|
26
26
|
@in_itsi_file = true
|
27
27
|
CompletionListener.new(response_builder, node_context, dispatcher, uri)
|
28
28
|
end
|
29
29
|
|
30
30
|
def create_hover_listener(response_builder, node_context, dispatcher)
|
31
31
|
hl = dispatcher.listeners[:on_call_node_enter].find { |c| c.is_a?(RubyLsp::Listeners::Hover) }
|
32
|
-
return unless hl.instance_variable_get("@path").to_s.
|
32
|
+
return unless hl.instance_variable_get("@path").to_s =~ /itsi.rb$/i
|
33
|
+
|
33
34
|
HoverListener.new(response_builder, node_context, dispatcher)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
class HoverListener
|
38
|
+
class HoverListener # rubocop:disable Style/Documentation
|
38
39
|
def initialize(response_builder, node_context, dispatcher)
|
39
40
|
@response_builder = response_builder
|
40
41
|
@node_context = node_context
|
41
42
|
@dispatcher = dispatcher
|
42
43
|
|
43
|
-
@options_by_name = ::Itsi::Server::Config::Option.subclasses.group_by(&:option_name).
|
44
|
-
@middlewares_by_name = ::Itsi::Server::Config::Middleware.subclasses.group_by(&:middleware_name).
|
44
|
+
@options_by_name = ::Itsi::Server::Config::Option.subclasses.group_by(&:option_name).transform_values(&:first)
|
45
|
+
@middlewares_by_name = ::Itsi::Server::Config::Middleware.subclasses.group_by(&:middleware_name).transform_values(&:first)
|
45
46
|
# Register for call nodes for hover events
|
46
47
|
dispatcher.register(self, :on_call_node_enter)
|
47
48
|
end
|
48
49
|
|
49
|
-
def on_call_node_enter(node)
|
50
|
+
def on_call_node_enter(node) # rubocop:disable Metrics/MethodLength
|
50
51
|
if (matched_class = @options_by_name[node.message.to_sym])
|
51
52
|
@response_builder.push(
|
52
53
|
matched_class.documentation,
|
@@ -61,7 +62,7 @@ module RubyLsp
|
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
|
-
class CompletionListener
|
65
|
+
class CompletionListener # rubocop:disable Style/Documentation
|
65
66
|
def initialize(response_builder, node_context, dispatcher, uri)
|
66
67
|
@response_builder = response_builder
|
67
68
|
@node_context = node_context
|
@@ -74,7 +75,7 @@ module RubyLsp
|
|
74
75
|
dispatcher.register(self, :completion_item_resolve)
|
75
76
|
end
|
76
77
|
|
77
|
-
def on_call_node_enter(node)
|
78
|
+
def on_call_node_enter(node) # rubocop:disable Metrics/AbcSize
|
78
79
|
# Only handle method calls that are being typed (i.e. no arguments yet)
|
79
80
|
return unless node.arguments.nil?
|
80
81
|
|
@@ -122,8 +123,6 @@ module RubyLsp
|
|
122
123
|
end
|
123
124
|
end
|
124
125
|
end
|
125
|
-
|
126
|
-
|
127
126
|
end
|
128
127
|
end
|
129
128
|
end
|
@@ -25,17 +25,10 @@ def free_bind(protocol = "http", unix_socket: false)
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def server(
|
29
|
-
|
28
|
+
def server(
|
29
|
+
app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(protocol), itsi_rb: nil, cleanup: true,
|
30
|
+
&blk)
|
30
31
|
app ||= Rack::Lint.new(app_with_lint) if app_with_lint
|
31
|
-
itsi_rb ||= lambda do
|
32
|
-
# Inline Itsi.rb
|
33
|
-
bind bind
|
34
|
-
workers 1
|
35
|
-
threads 1
|
36
|
-
log_level :warn
|
37
|
-
run app if app
|
38
|
-
end
|
39
32
|
|
40
33
|
cli_params = {}
|
41
34
|
cli_params[:binds] = [bind] if bind
|
@@ -46,13 +39,18 @@ def server(app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(proto
|
|
46
39
|
sync.push(true)
|
47
40
|
end
|
48
41
|
|
49
|
-
Itsi::Server.start_in_background_thread(cli_params
|
42
|
+
Itsi::Server.start_in_background_thread(cli_params) do
|
43
|
+
bind bind
|
44
|
+
workers 1
|
45
|
+
threads 1
|
46
|
+
log_level :warn
|
47
|
+
run app if app
|
48
|
+
instance_exec(&itsi_rb) if itsi_rb
|
49
|
+
end
|
50
50
|
|
51
51
|
sync.pop
|
52
52
|
uri = URI(bind)
|
53
|
-
# Timeout.timeout(timeout) do
|
54
53
|
RequestContext.new(uri, self).instance_exec(uri, &blk)
|
55
|
-
# end
|
56
54
|
rescue StandardError => e
|
57
55
|
puts e
|
58
56
|
# puts e.message
|
@@ -119,6 +117,7 @@ class RequestContext
|
|
119
117
|
def patch(path, data = "", headers = {})
|
120
118
|
request = Net::HTTP::Patch.new(uri_for(path))
|
121
119
|
request.body = data
|
120
|
+
headers.each { |k, v| request[k] = v }
|
122
121
|
client.request(request)
|
123
122
|
end
|
124
123
|
|
@@ -5,14 +5,13 @@ class TestGrpc < Minitest::Test
|
|
5
5
|
Stub = Test::TestService::Stub
|
6
6
|
|
7
7
|
def new_stub(uri)
|
8
|
-
address = uri.to_s[
|
8
|
+
address = uri.to_s[%r{//(.*)}, 1] # e.g. "127.0.0.1:12345"
|
9
9
|
channel = GRPC::Core::Channel.new(address,
|
10
|
-
{},
|
11
|
-
:this_channel_is_insecure
|
12
|
-
)
|
10
|
+
{}, # channel_args hash
|
11
|
+
:this_channel_is_insecure)
|
13
12
|
stub = Stub.new(nil,
|
14
|
-
|
15
|
-
|
13
|
+
nil,
|
14
|
+
channel_override: channel)
|
16
15
|
end
|
17
16
|
|
18
17
|
def test_unary_echo
|
@@ -46,7 +45,7 @@ class TestGrpc < Minitest::Test
|
|
46
45
|
req = Test::EchoRequest.new(message: "xy")
|
47
46
|
# expect two StreamResponse frames, one per character
|
48
47
|
chars = stub.server_stream(req).map(&:messages).flatten
|
49
|
-
assert_equal [
|
48
|
+
assert_equal %w[x y], chars
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
@@ -58,7 +57,7 @@ class TestGrpc < Minitest::Test
|
|
58
57
|
inputs = %w[test1 test2].map { |m| Test::EchoRequest.new(message: m) }
|
59
58
|
# each response uppercases its incoming message
|
60
59
|
results = stub.bidi_stream(inputs.each).map(&:message)
|
61
|
-
assert_equal [
|
60
|
+
assert_equal %w[TEST1 TEST2], results
|
62
61
|
end
|
63
62
|
end
|
64
63
|
|
@@ -82,7 +81,6 @@ class TestGrpc < Minitest::Test
|
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
85
|
-
|
86
84
|
def test_unary_echo_json
|
87
85
|
server(itsi_rb: lambda do
|
88
86
|
grpc TestServiceImpl.new
|
@@ -99,7 +97,7 @@ class TestGrpc < Minitest::Test
|
|
99
97
|
server(itsi_rb: lambda do
|
100
98
|
grpc TestServiceImpl.new
|
101
99
|
end) do
|
102
|
-
input = [{"message" => "a"}, {"message" => "b"}, {"message" => "c"}]
|
100
|
+
input = [{ "message" => "a" }, { "message" => "b" }, { "message" => "c" }]
|
103
101
|
res = post("test.TestService/ClientStream", input.to_json, { "Content-Type" => "application/json" })
|
104
102
|
json = JSON.parse(res.body)
|
105
103
|
assert_equal 200, res.code.to_i
|
@@ -117,7 +115,7 @@ class TestGrpc < Minitest::Test
|
|
117
115
|
# service streams back one JSON object per character
|
118
116
|
messages = arr.flat_map { |frame| frame["messages"] }
|
119
117
|
assert_equal 200, res.code.to_i
|
120
|
-
assert_equal [
|
118
|
+
assert_equal %w[x y], messages
|
121
119
|
end
|
122
120
|
end
|
123
121
|
|
@@ -125,13 +123,13 @@ class TestGrpc < Minitest::Test
|
|
125
123
|
server(itsi_rb: lambda do
|
126
124
|
grpc TestServiceImpl.new
|
127
125
|
end) do
|
128
|
-
inputs = [{"message":"foo"}, {"message":"Bar"}]
|
126
|
+
inputs = [{ "message": "foo" }, { "message": "Bar" }]
|
129
127
|
res = post("test.TestService/BidiStream", inputs.to_json, { "Content-Type" => "application/json" })
|
130
128
|
arr = JSON.parse(res.body)
|
131
129
|
# bidi uppercases each incoming message
|
132
130
|
results = arr.map { |frame| frame["message"] }
|
133
131
|
assert_equal 200, res.code.to_i
|
134
|
-
assert_equal [
|
132
|
+
assert_equal %w[FOO BAR], results
|
135
133
|
end
|
136
134
|
end
|
137
135
|
|
@@ -145,7 +143,8 @@ class TestGrpc < Minitest::Test
|
|
145
143
|
assert_nil json1["messages"]
|
146
144
|
|
147
145
|
# empty server-stream
|
148
|
-
res2 = post("test.TestService/ServerStream", { "message" => "" }.to_json,
|
146
|
+
res2 = post("test.TestService/ServerStream", { "message" => "" }.to_json,
|
147
|
+
{ "Content-Type" => "application/json" })
|
149
148
|
arr2 = JSON.parse(res2.body)
|
150
149
|
assert arr2.empty?
|
151
150
|
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "test_service_services_pb" # generated by grpc_tools_ruby_protoc
|
2
2
|
|
3
3
|
class TestServiceImpl < Test::TestService::Service
|
4
4
|
def unary_echo(req, _unused_call)
|
5
5
|
Test::EchoResponse.new(message: req.message)
|
6
6
|
end
|
7
7
|
|
8
|
-
def client_stream(
|
9
|
-
msgs =
|
8
|
+
def client_stream(call)
|
9
|
+
msgs = call.each_remote_read.map(&:message)
|
10
10
|
Test::StreamResponse.new(messages: msgs)
|
11
11
|
end
|
12
12
|
|