restate-sdk 0.6.0 → 0.8.0
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/Cargo.lock +1 -1
- data/README.md +31 -14
- data/ext/restate_internal/Cargo.toml +1 -1
- data/lib/restate/client.rb +157 -0
- data/lib/restate/config.rb +35 -0
- data/lib/restate/context.rb +13 -128
- data/lib/restate/discovery.rb +6 -15
- data/lib/restate/durable_future.rb +15 -39
- data/lib/restate/endpoint.rb +5 -22
- data/lib/restate/errors.rb +2 -15
- data/lib/restate/handler.rb +21 -20
- data/lib/restate/serde.rb +14 -130
- data/lib/restate/server.rb +10 -26
- data/lib/restate/server_context.rb +50 -248
- data/lib/restate/service.rb +24 -3
- data/lib/restate/service_dsl.rb +70 -6
- data/lib/restate/service_proxy.rb +73 -0
- data/lib/restate/testing.rb +1 -1
- data/lib/restate/version.rb +2 -2
- data/lib/restate/virtual_object.rb +27 -4
- data/lib/restate/vm.rb +9 -74
- data/lib/restate/workflow.rb +27 -4
- data/lib/restate.rb +222 -62
- data/sig/restate.rbs +196 -0
- metadata +6 -18
- data/lib/tapioca/dsl/compilers/restate.rb +0 -116
- data/rbi/restate-sdk.rbi +0 -307
data/lib/restate/server.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: ignore
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'async'
|
|
@@ -14,21 +14,17 @@ module Restate
|
|
|
14
14
|
# GET /health → health check
|
|
15
15
|
# POST /invoke/:service/:handler → handler invocation
|
|
16
16
|
class Server
|
|
17
|
-
|
|
17
|
+
SDK_VERSION = Internal::SDK_VERSION
|
|
18
|
+
X_RESTATE_SERVER = "restate-sdk-ruby/#{SDK_VERSION}".freeze
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
X_RESTATE_SERVER = T.let("restate-sdk-ruby/#{SDK_VERSION}".freeze, String)
|
|
20
|
+
LOGGER = Logger.new($stdout, progname: 'Restate::Server')
|
|
21
21
|
|
|
22
|
-
LOGGER = T.let(Logger.new($stdout, progname: 'Restate::Server'), Logger)
|
|
23
|
-
|
|
24
|
-
sig { params(endpoint: Endpoint).void }
|
|
25
22
|
def initialize(endpoint)
|
|
26
|
-
@endpoint =
|
|
27
|
-
@identity_verifier =
|
|
23
|
+
@endpoint = endpoint
|
|
24
|
+
@identity_verifier = Internal::IdentityVerifier.new(endpoint.identity_keys)
|
|
28
25
|
end
|
|
29
26
|
|
|
30
27
|
# Rack interface
|
|
31
|
-
sig { params(env: T::Hash[String, T.untyped]).returns(T.untyped) }
|
|
32
28
|
def call(env)
|
|
33
29
|
path = env['PATH_INFO'] || '/'
|
|
34
30
|
parsed = parse_path(path)
|
|
@@ -51,7 +47,6 @@ module Restate
|
|
|
51
47
|
|
|
52
48
|
private
|
|
53
49
|
|
|
54
|
-
sig { params(path: String).returns(T::Hash[Symbol, T.untyped]) }
|
|
55
50
|
def parse_path(path)
|
|
56
51
|
segments = path.split('/').reject(&:empty?)
|
|
57
52
|
|
|
@@ -77,22 +72,18 @@ module Restate
|
|
|
77
72
|
end
|
|
78
73
|
end
|
|
79
74
|
|
|
80
|
-
sig { returns(T.untyped) }
|
|
81
75
|
def health_response
|
|
82
76
|
[200, { 'content-type' => 'application/json', 'x-restate-server' => X_RESTATE_SERVER }, ['{"status":"ok"}']]
|
|
83
77
|
end
|
|
84
78
|
|
|
85
|
-
sig { returns(T.untyped) }
|
|
86
79
|
def not_found_response
|
|
87
80
|
[404, { 'x-restate-server' => X_RESTATE_SERVER }, ['']]
|
|
88
81
|
end
|
|
89
82
|
|
|
90
|
-
sig { params(status: Integer, message: String).returns(T.untyped) }
|
|
91
83
|
def error_response(status, message)
|
|
92
84
|
[status, { 'content-type' => 'text/plain', 'x-restate-server' => X_RESTATE_SERVER }, [message]]
|
|
93
85
|
end
|
|
94
86
|
|
|
95
|
-
sig { params(env: T::Hash[String, T.untyped]).returns(T.untyped) }
|
|
96
87
|
def handle_discover(env)
|
|
97
88
|
# Detect HTTP version for protocol mode
|
|
98
89
|
http_version = env['HTTP_VERSION'] || env['SERVER_PROTOCOL'] || 'HTTP/1.1'
|
|
@@ -119,7 +110,6 @@ module Restate
|
|
|
119
110
|
end
|
|
120
111
|
end
|
|
121
112
|
|
|
122
|
-
sig { params(accept: String).returns(T.nilable(Integer)) }
|
|
123
113
|
def negotiate_version(accept)
|
|
124
114
|
if accept.include?('application/vnd.restate.endpointmanifest.v4+json')
|
|
125
115
|
4
|
|
@@ -132,7 +122,6 @@ module Restate
|
|
|
132
122
|
end
|
|
133
123
|
end
|
|
134
124
|
|
|
135
|
-
sig { params(env: T::Hash[String, T.untyped], service_name: T.untyped, handler_name: T.untyped).returns(T.untyped) }
|
|
136
125
|
def handle_invocation(env, service_name, handler_name)
|
|
137
126
|
# Verify identity
|
|
138
127
|
request_headers = extract_headers(env)
|
|
@@ -154,7 +143,6 @@ module Restate
|
|
|
154
143
|
process_invocation(env, handler, request_headers)
|
|
155
144
|
end
|
|
156
145
|
|
|
157
|
-
sig { params(env: T::Hash[String, T.untyped], handler: T.untyped, request_headers: T.untyped).returns(T.untyped) }
|
|
158
146
|
def process_invocation(env, handler, request_headers)
|
|
159
147
|
vm = VMWrapper.new(request_headers)
|
|
160
148
|
status, response_headers = vm.get_response_head
|
|
@@ -171,7 +159,7 @@ module Restate
|
|
|
171
159
|
# Read request body chunks and feed to VM until ready to execute,
|
|
172
160
|
# then continue feeding remaining chunks via the input queue.
|
|
173
161
|
rack_input = env['rack.input']
|
|
174
|
-
ready =
|
|
162
|
+
ready = false
|
|
175
163
|
if rack_input
|
|
176
164
|
# Feed chunks until the VM has enough to start execution
|
|
177
165
|
while (chunk = rack_input.read_partial(16_384))
|
|
@@ -246,11 +234,8 @@ module Restate
|
|
|
246
234
|
# Rack 3 streaming body that yields chunks from an Async::Queue.
|
|
247
235
|
# Terminates when nil is dequeued.
|
|
248
236
|
class StreamingBody
|
|
249
|
-
extend T::Sig
|
|
250
|
-
|
|
251
|
-
sig { params(queue: Async::Queue).void }
|
|
252
237
|
def initialize(queue)
|
|
253
|
-
@queue =
|
|
238
|
+
@queue = queue
|
|
254
239
|
end
|
|
255
240
|
|
|
256
241
|
def each
|
|
@@ -263,13 +248,12 @@ module Restate
|
|
|
263
248
|
end
|
|
264
249
|
end
|
|
265
250
|
|
|
266
|
-
sig { params(env: T::Hash[String, T.untyped]).returns(T::Array[T::Array[String]]) }
|
|
267
251
|
def extract_headers(env)
|
|
268
|
-
headers =
|
|
252
|
+
headers = []
|
|
269
253
|
env.each do |key, value|
|
|
270
254
|
next unless key.start_with?('HTTP_')
|
|
271
255
|
|
|
272
|
-
header_name = key.
|
|
256
|
+
header_name = key.byteslice(5..).tr('_', '-').downcase!
|
|
273
257
|
headers << [header_name, value]
|
|
274
258
|
end
|
|
275
259
|
# Also include content-type and content-length if present
|