Skip to content

Commit 1ce9c45

Browse files
Add gRPC example.
1 parent 8292c26 commit 1ce9c45

File tree

11 files changed

+400
-0
lines changed

11 files changed

+400
-0
lines changed

examples/grpc/bake.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# frozen_string_literal: true
2+
3+
def build
4+
system("grpc_tools_ruby_protoc", "--ruby_out=.", "--grpc_out=.", "--proto_path=.", "my_service.proto")
5+
end

examples/grpc/client.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require "grpc"
5+
require_relative "my_service_services_pb"
6+
7+
def main
8+
# Create a stub for the Greeter service
9+
stub = MyService::Greeter::Stub.new("localhost:50051", :this_channel_is_insecure)
10+
11+
# Create and populate a HelloRequest object
12+
request = MyService::HelloRequest.new(name: "World")
13+
14+
# Call the SayHello method
15+
response = stub.say_hello(request)
16+
17+
# Print the response message
18+
puts response.message
19+
end
20+
21+
# Run the client
22+
main

examples/grpc/config.ru

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
require "grpc"
4+
require_relative "my_service_services_pb" # Adjust the path as needed
5+
require_relative "my_service_pb" # Adjust the path as needed
6+
7+
# Define the service handling
8+
class GreeterService
9+
def say_hello(hello_req, _unused_call)
10+
name = hello_req.name
11+
12+
return MyService::HelloReply.new(message: "Hello, #{name}!")
13+
end
14+
end
15+
16+
run do |env|
17+
# Check if it's a gRPC request by looking for the Content-Type
18+
if env["CONTENT_TYPE"] == "application/grpc"
19+
# Get the input data
20+
input = env["rack.input"]
21+
prefix = input.read(5)
22+
request_body = input.read
23+
24+
# Deserialize the request using the gRPC module for HelloRequest
25+
hello_request = MyService::HelloRequest.decode(request_body)
26+
27+
# Create the service instance and call the method
28+
service = GreeterService.new
29+
response = service.say_hello(hello_request, nil)
30+
31+
# Prepare the response
32+
encoded_response = response.to_proto
33+
34+
# Create a length-prefixed response
35+
response_length = [encoded_response.bytesize].pack("N") # Length in big-endian format
36+
compression_flag = "\x00" # 0 for no compression
37+
response_with_prefix = compression_flag + response_length + encoded_response
38+
39+
# Set the headers for the HTTP response
40+
headers = {
41+
"content-type" => "application/grpc+proto",
42+
"grpc-status" => "0" # OK
43+
}
44+
45+
[200, headers, [response_with_prefix]]
46+
else
47+
[400, { "Content-Type" => "text/plain" }, ["Unsupported Content-Type"]]
48+
end
49+
end

examples/grpc/falcon.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env falcon-host
2+
# frozen_string_literal: true
3+
4+
# Released under the MIT License.
5+
# Copyright, 2025, by Samuel Williams.
6+
7+
require "falcon/environment/application"
8+
require_relative "my_service_services_pb"
9+
10+
# Define the service handling
11+
class GreeterService
12+
def say_hello(hello_req, _unused_call)
13+
name = hello_req.name
14+
15+
return MyService::HelloReply.new(message: "Hello, #{name}!")
16+
end
17+
end
18+
19+
class MyApplication
20+
def call(request)
21+
body = request.read
22+
prefix = body[0..5]
23+
message = body[5..-1]
24+
25+
# Deserialize the request using the gRPC module for HelloRequest
26+
hello_request = MyService::HelloRequest.decode(message)
27+
28+
# Create the service instance and call the method
29+
service = GreeterService.new
30+
response = service.say_hello(hello_request, nil)
31+
32+
# Prepare the response
33+
encoded_response = response.to_proto
34+
35+
# Create a length-prefixed response
36+
response_length = [encoded_response.bytesize].pack("N") # Length in big-endian format
37+
compression_flag = "\x00" # 0 for no compression
38+
response_with_prefix = compression_flag + response_length + encoded_response
39+
40+
# Set the headers for the HTTP response
41+
headers = ::Protocol::HTTP::Headers.new
42+
headers["content-type"] = "application/grpc+proto"
43+
headers.trailer!
44+
headers["grpc-status"] = "0"
45+
46+
return ::Protocol::HTTP::Response[200, headers, [response_with_prefix]]
47+
end
48+
end
49+
50+
service "hello.localhost" do
51+
include Falcon::Environment::Application
52+
53+
middleware do
54+
MyApplication.new
55+
end
56+
57+
scheme "http"
58+
protocol {Async::HTTP::Protocol::HTTP2}
59+
60+
endpoint do
61+
Async::HTTP::Endpoint.for(scheme, "localhost", port: 50051, protocol: protocol)
62+
end
63+
end

examples/grpc/gems.locked

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
PATH
2+
remote: ../..
3+
specs:
4+
falcon (0.52.3)
5+
async
6+
async-container (~> 0.20)
7+
async-container-supervisor (~> 0.5.0)
8+
async-http (~> 0.75)
9+
async-http-cache (~> 0.4)
10+
async-service (~> 0.10)
11+
bundler
12+
localhost (~> 1.1)
13+
openssl (~> 3.0)
14+
protocol-http (~> 0.31)
15+
protocol-rack (~> 0.7)
16+
samovar (~> 2.3)
17+
18+
GEM
19+
remote: https://rubygems.org/
20+
specs:
21+
async (2.33.0)
22+
console (~> 1.29)
23+
fiber-annotation
24+
io-event (~> 1.11)
25+
metrics (~> 0.12)
26+
traces (~> 0.18)
27+
async-container (0.27.0)
28+
async (~> 2.22)
29+
async-container-supervisor (0.5.2)
30+
async-container (~> 0.22)
31+
async-service
32+
io-endpoint
33+
io-stream
34+
memory-leak (~> 0.5)
35+
async-http (0.91.0)
36+
async (>= 2.10.2)
37+
async-pool (~> 0.11)
38+
io-endpoint (~> 0.14)
39+
io-stream (~> 0.6)
40+
metrics (~> 0.12)
41+
protocol-http (~> 0.49)
42+
protocol-http1 (~> 0.30)
43+
protocol-http2 (~> 0.22)
44+
traces (~> 0.10)
45+
async-http-cache (0.4.5)
46+
async-http (~> 0.56)
47+
async-pool (0.11.0)
48+
async (>= 2.0)
49+
async-service (0.14.4)
50+
async
51+
async-container (~> 0.16)
52+
string-format (~> 0.2)
53+
bake (0.24.1)
54+
bigdecimal
55+
samovar (~> 2.1)
56+
bigdecimal (3.2.3)
57+
console (1.34.0)
58+
fiber-annotation
59+
fiber-local (~> 1.1)
60+
json
61+
fiber-annotation (0.2.0)
62+
fiber-local (1.1.0)
63+
fiber-storage
64+
fiber-storage (1.0.1)
65+
google-protobuf (4.32.1)
66+
bigdecimal
67+
rake (>= 13)
68+
google-protobuf (4.32.1-aarch64-linux-gnu)
69+
bigdecimal
70+
rake (>= 13)
71+
google-protobuf (4.32.1-arm64-darwin)
72+
bigdecimal
73+
rake (>= 13)
74+
google-protobuf (4.32.1-x86-linux-gnu)
75+
bigdecimal
76+
rake (>= 13)
77+
google-protobuf (4.32.1-x86_64-darwin)
78+
bigdecimal
79+
rake (>= 13)
80+
google-protobuf (4.32.1-x86_64-linux-gnu)
81+
bigdecimal
82+
rake (>= 13)
83+
googleapis-common-protos-types (1.21.0)
84+
google-protobuf (~> 4.26)
85+
grpc (1.75.0)
86+
google-protobuf (>= 3.25, < 5.0)
87+
googleapis-common-protos-types (~> 1.0)
88+
grpc (1.75.0-aarch64-linux-gnu)
89+
google-protobuf (>= 3.25, < 5.0)
90+
googleapis-common-protos-types (~> 1.0)
91+
grpc (1.75.0-arm64-darwin)
92+
google-protobuf (>= 3.25, < 5.0)
93+
googleapis-common-protos-types (~> 1.0)
94+
grpc (1.75.0-x86-linux-gnu)
95+
google-protobuf (>= 3.25, < 5.0)
96+
googleapis-common-protos-types (~> 1.0)
97+
grpc (1.75.0-x86_64-darwin)
98+
google-protobuf (>= 3.25, < 5.0)
99+
googleapis-common-protos-types (~> 1.0)
100+
grpc (1.75.0-x86_64-linux-gnu)
101+
google-protobuf (>= 3.25, < 5.0)
102+
googleapis-common-protos-types (~> 1.0)
103+
grpc-tools (1.75.0)
104+
io-endpoint (0.15.2)
105+
io-event (1.14.0)
106+
io-stream (0.10.0)
107+
json (2.15.0)
108+
localhost (1.6.0)
109+
mapping (1.1.3)
110+
memory-leak (0.5.2)
111+
metrics (0.15.0)
112+
openssl (3.3.0)
113+
protocol-hpack (1.5.1)
114+
protocol-http (0.54.0)
115+
protocol-http1 (0.35.1)
116+
protocol-http (~> 0.22)
117+
protocol-http2 (0.23.0)
118+
protocol-hpack (~> 1.4)
119+
protocol-http (~> 0.47)
120+
protocol-rack (0.16.0)
121+
io-stream (>= 0.10)
122+
protocol-http (~> 0.43)
123+
rack (>= 1.0)
124+
rack (3.2.1)
125+
rake (13.3.0)
126+
samovar (2.3.0)
127+
console (~> 1.0)
128+
mapping (~> 1.0)
129+
string-format (0.2.0)
130+
traces (0.18.2)
131+
132+
PLATFORMS
133+
aarch64-linux
134+
arm64-darwin
135+
ruby
136+
x86-linux
137+
x86_64-darwin
138+
x86_64-linux
139+
140+
DEPENDENCIES
141+
bake
142+
falcon!
143+
grpc
144+
grpc-tools
145+
146+
BUNDLED WITH
147+
2.6.9

examples/grpc/gems.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
5+
gem "falcon", path: "../.."
6+
gem "bake"
7+
8+
gem "grpc"
9+
gem "grpc-tools"

examples/grpc/my_service.proto

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
syntax = "proto3";
2+
3+
package my_service;
4+
5+
// The request message containing the user's name.
6+
message HelloRequest {
7+
string name = 1;
8+
}
9+
10+
// The response message containing the greetings.
11+
message HelloReply {
12+
string message = 1;
13+
}
14+
15+
// The greeting service definition.
16+
service Greeter {
17+
rpc SayHello(HelloRequest) returns (HelloReply);
18+
// Server streaming - like Spanner's streaming results
19+
rpc StreamNumbers(HelloRequest) returns (stream HelloReply);
20+
}

examples/grpc/my_service_pb.rb

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/grpc/my_service_services_pb.rb

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/grpc/regenerate_proto.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
# Regenerate the Ruby protobuf and gRPC service files
3+
4+
grpc_tools_ruby_protoc \
5+
--ruby_out=. \
6+
--grpc_out=. \
7+
--plugin=protoc-gen-grpc=$(which grpc_tools_ruby_protoc_plugin) \
8+
my_service.proto
9+
10+
echo "Generated:"
11+
echo " - my_service_pb.rb"
12+
echo " - my_service_services_pb.rb"
13+
14+
15+
16+
17+

0 commit comments

Comments
 (0)