proc 0.1.2 → 0.6.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/lib/proc.rb +8 -0
- data/lib/proc/argument.rb +2 -2
- data/lib/proc/callable.rb +15 -12
- data/lib/proc/client.rb +96 -56
- data/lib/proc/composition.rb +25 -20
- data/lib/proc/http/client.rb +15 -20
- data/lib/proc/version.rb +1 -1
- metadata +17 -4
- data/lib/proc/null_logger.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1759094e21f61007e2f96393615f5ae03880bff36f6ee764e1072ba7b73bd310
|
4
|
+
data.tar.gz: 7495016b1b5e9de6e4d8a8c92dce90b4769f6404488d92b69f88ab06238ee6cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '00008d07672ae0a0aed43d4146b0c6ea687071d939085e19cc7ae82aabc770e33dcb959d53ec69705784c667ffdad75545650e97872870ccd1396285b034149c'
|
7
|
+
data.tar.gz: b7d89543b58a65bdd9522bf360c2a76132f2a7a391717af3d1f0fb665e49b0157b85081cfcd0ddacb289e82c5cb87036946da10944b16645550e03aa72329a1b
|
data/lib/proc.rb
CHANGED
data/lib/proc/argument.rb
CHANGED
@@ -8,7 +8,7 @@ class Proc
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def serialize
|
11
|
-
|
11
|
+
["@@", @name.to_s, serialized_options]
|
12
12
|
end
|
13
13
|
|
14
14
|
def serialized_options
|
@@ -21,7 +21,7 @@ class Proc
|
|
21
21
|
if value.respond_to?(:serialize)
|
22
22
|
value.serialize
|
23
23
|
else
|
24
|
-
value
|
24
|
+
["%%", value]
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
data/lib/proc/callable.rb
CHANGED
@@ -4,8 +4,8 @@ class Proc
|
|
4
4
|
class Callable
|
5
5
|
attr_reader :proc, :input, :arguments
|
6
6
|
|
7
|
-
def initialize(proc, client:, input:
|
8
|
-
@proc = proc
|
7
|
+
def initialize(proc, client:, input: Proc.undefined, arguments: {})
|
8
|
+
@proc = proc.to_s
|
9
9
|
@client = client
|
10
10
|
@input = input
|
11
11
|
@arguments = arguments
|
@@ -24,7 +24,7 @@ class Proc
|
|
24
24
|
arguments: @arguments.merge(arguments)
|
25
25
|
)
|
26
26
|
|
27
|
-
@client.call(@proc, callable.
|
27
|
+
@client.call(@proc, callable.input, **callable.arguments)
|
28
28
|
end
|
29
29
|
|
30
30
|
def with(input = input_omitted = true, **arguments)
|
@@ -44,12 +44,15 @@ class Proc
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def serialize
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
serialized = ["()", @proc]
|
48
|
+
|
49
|
+
unless Proc.undefined?(@input)
|
50
|
+
serialized << [">>", serialized_input]
|
51
|
+
end
|
52
|
+
|
53
|
+
serialized.concat(serialized_arguments)
|
54
|
+
|
55
|
+
["{}", serialized]
|
53
56
|
end
|
54
57
|
|
55
58
|
def serialized_input
|
@@ -57,8 +60,8 @@ class Proc
|
|
57
60
|
end
|
58
61
|
|
59
62
|
def serialized_arguments
|
60
|
-
@arguments.
|
61
|
-
|
63
|
+
@arguments.map { |key, value|
|
64
|
+
["$$", key.to_s, serialize_value(value)]
|
62
65
|
}
|
63
66
|
end
|
64
67
|
|
@@ -98,7 +101,7 @@ class Proc
|
|
98
101
|
if value.respond_to?(:serialize)
|
99
102
|
value.serialize
|
100
103
|
else
|
101
|
-
value
|
104
|
+
["%%", value]
|
102
105
|
end
|
103
106
|
end
|
104
107
|
end
|
data/lib/proc/client.rb
CHANGED
@@ -6,10 +6,16 @@ require "oj"
|
|
6
6
|
require_relative "argument"
|
7
7
|
require_relative "callable"
|
8
8
|
require_relative "composition"
|
9
|
-
require_relative "null_logger"
|
10
9
|
|
11
10
|
require_relative "http/client"
|
12
11
|
|
12
|
+
Console.logger.off!
|
13
|
+
|
14
|
+
Oj.default_options = {
|
15
|
+
mode: :custom,
|
16
|
+
bigdecimal_load: :auto
|
17
|
+
}.freeze
|
18
|
+
|
13
19
|
class Proc
|
14
20
|
class Error < StandardError
|
15
21
|
end
|
@@ -35,13 +41,12 @@ class Proc
|
|
35
41
|
class Timeout < Error
|
36
42
|
end
|
37
43
|
|
38
|
-
class Client
|
44
|
+
class Client
|
39
45
|
def initialize(authorization, scheme: "https", host: "proc.dev")
|
40
46
|
@authorization = authorization
|
41
47
|
@scheme = scheme
|
42
48
|
@host = host
|
43
|
-
|
44
|
-
super()
|
49
|
+
@internal = Http::Client.new
|
45
50
|
end
|
46
51
|
|
47
52
|
def [](proc)
|
@@ -65,64 +70,59 @@ class Proc
|
|
65
70
|
end
|
66
71
|
|
67
72
|
DEFAULT_HEADERS = {
|
68
|
-
"accept" => "application/json",
|
69
|
-
"content-type" => "application/json"
|
73
|
+
"accept" => "application/vnd.proc+json",
|
74
|
+
"content-type" => "application/vnd.proc+json"
|
70
75
|
}.freeze
|
71
76
|
|
72
|
-
def call(proc = nil, input =
|
73
|
-
|
74
|
-
body = { "<<" => serialize_value(input) }
|
75
|
-
|
76
|
-
arguments.each_pair do |key, value|
|
77
|
-
body[key.to_s] = serialize_value(value)
|
78
|
-
end
|
79
|
-
|
80
|
-
headers = {
|
81
|
-
"authorization" => "bearer #{@authorization}"
|
82
|
-
}.merge(DEFAULT_HEADERS)
|
77
|
+
def call(proc = nil, input = Proc.undefined, **arguments)
|
78
|
+
body = []
|
83
79
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
@remaining = response.headers["x-rate-limit-remaining"].to_s.to_i
|
88
|
-
@resets_at = Time.at(response.headers["x-rate-limit-reset"].to_s.to_i)
|
80
|
+
unless Proc.undefined?(input)
|
81
|
+
body << [">>", serialize_value(input)]
|
82
|
+
end
|
89
83
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
#
|
94
|
-
raise Proc::Unavailable, error.message
|
95
|
-
ensure
|
96
|
-
response&.close
|
97
|
-
end
|
84
|
+
arguments.each_pair do |key, value|
|
85
|
+
body << ["$$", key.to_s, serialize_value(value)]
|
86
|
+
end
|
98
87
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
88
|
+
headers = {
|
89
|
+
"authorization" => "bearer #{@authorization}"
|
90
|
+
}.merge(DEFAULT_HEADERS)
|
91
|
+
|
92
|
+
status, payload = get_payload(proc: proc, headers: headers, body: body)
|
93
|
+
|
94
|
+
case status
|
95
|
+
when 200
|
96
|
+
extract_output(payload)
|
97
|
+
when 400
|
98
|
+
raise Proc::Invalid, extract_error_message(payload)
|
99
|
+
when 401
|
100
|
+
raise Proc::Unauthorized, extract_error_message(payload)
|
101
|
+
when 403
|
102
|
+
raise Proc::Forbidden, extract_error_message(payload)
|
103
|
+
when 404
|
104
|
+
raise Proc::Undefined, extract_error_message(payload)
|
105
|
+
when 408
|
106
|
+
raise Proc::Timeout, extract_error_message(payload)
|
107
|
+
when 413
|
108
|
+
raise Proc::Invalid, extract_error_message(payload)
|
109
|
+
when 429
|
110
|
+
raise Proc::Limited, extract_error_message(payload)
|
111
|
+
when 500
|
112
|
+
raise Proc::Error, extract_error_message(payload)
|
113
|
+
when 508
|
114
|
+
raise Proc::Error, extract_error_message(payload)
|
115
|
+
else
|
116
|
+
raise Proc::Error, "unhandled"
|
117
|
+
end
|
122
118
|
end
|
123
119
|
|
124
|
-
def method_missing(name, input =
|
125
|
-
|
120
|
+
def method_missing(name, input = input_omitted = true, *, **arguments)
|
121
|
+
if input_omitted
|
122
|
+
Callable.new(name, client: self, arguments: arguments)
|
123
|
+
else
|
124
|
+
Callable.new(name, client: self, input: input, arguments: arguments)
|
125
|
+
end
|
126
126
|
end
|
127
127
|
|
128
128
|
def respond_to_missing?(name, *)
|
@@ -134,6 +134,10 @@ class Proc
|
|
134
134
|
end
|
135
135
|
alias_method :arg, :argument
|
136
136
|
|
137
|
+
def close
|
138
|
+
@internal.close
|
139
|
+
end
|
140
|
+
|
137
141
|
private def build_uri(proc)
|
138
142
|
host_and_path = File.join(@host, proc.to_s.split(".").join("/"))
|
139
143
|
|
@@ -144,8 +148,44 @@ class Proc
|
|
144
148
|
if value.respond_to?(:serialize)
|
145
149
|
value.serialize
|
146
150
|
else
|
147
|
-
value
|
151
|
+
["%%", value]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
private def get_payload(proc:, headers:, body:)
|
156
|
+
@internal.call(:post, build_uri(proc), headers: headers, body: Oj.dump(body)) do |response|
|
157
|
+
@remaining = response.headers["x-rate-limit-remaining"].to_s.to_i
|
158
|
+
@resets_at = Time.at(response.headers["x-rate-limit-reset"].to_s.to_i)
|
159
|
+
[response.status, Oj.load(response.read)]
|
160
|
+
end
|
161
|
+
rescue
|
162
|
+
raise Proc::Unavailable
|
163
|
+
end
|
164
|
+
|
165
|
+
private def extract_output(payload)
|
166
|
+
payload.each do |tuple|
|
167
|
+
case tuple[0]
|
168
|
+
when "<<"
|
169
|
+
return tuple[1]
|
170
|
+
end
|
148
171
|
end
|
172
|
+
|
173
|
+
nil
|
174
|
+
end
|
175
|
+
|
176
|
+
private def extract_error(payload)
|
177
|
+
payload.each do |tuple|
|
178
|
+
case tuple[0]
|
179
|
+
when "!!"
|
180
|
+
return tuple[1]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
nil
|
185
|
+
end
|
186
|
+
|
187
|
+
private def extract_error_message(payload)
|
188
|
+
extract_error(payload)&.dig("message")
|
149
189
|
end
|
150
190
|
end
|
151
191
|
end
|
data/lib/proc/composition.rb
CHANGED
@@ -23,7 +23,7 @@ class Proc
|
|
23
23
|
arguments: @arguments.merge(arguments)
|
24
24
|
)
|
25
25
|
|
26
|
-
@client.call("
|
26
|
+
@client.call("exec", Proc.undefined, proc: callable)
|
27
27
|
end
|
28
28
|
|
29
29
|
def with(input = input_omitted = true, **arguments)
|
@@ -37,33 +37,38 @@ class Proc
|
|
37
37
|
|
38
38
|
def >>(other)
|
39
39
|
composed = dup
|
40
|
-
|
41
|
-
case other
|
42
|
-
when Composition
|
43
|
-
composed.merge(other)
|
44
|
-
when Callable
|
45
|
-
composed << other
|
46
|
-
end
|
47
|
-
|
40
|
+
composed << other
|
48
41
|
composed
|
49
42
|
end
|
50
43
|
|
51
44
|
def <<(callable)
|
52
|
-
|
45
|
+
case callable
|
46
|
+
when Composition
|
47
|
+
merge(callable)
|
48
|
+
when Callable
|
49
|
+
@callables << callable
|
50
|
+
end
|
53
51
|
end
|
54
52
|
|
55
53
|
def serialize
|
56
|
-
{
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
54
|
+
serialized = ["{}"]
|
55
|
+
|
56
|
+
unless Proc.undefined?(@input)
|
57
|
+
serialized << [">>", serialized_input]
|
58
|
+
end
|
59
|
+
|
60
|
+
serialized + serialized_arguments + serialized_calls
|
62
61
|
end
|
63
62
|
|
64
63
|
def serialized_calls
|
65
64
|
@callables.map { |callable|
|
66
|
-
[
|
65
|
+
serialized = ["()", callable.proc]
|
66
|
+
|
67
|
+
unless Proc.undefined?(callable.input)
|
68
|
+
serialized << [">>", callable.serialized_input]
|
69
|
+
end
|
70
|
+
|
71
|
+
serialized.concat(callable.serialized_arguments)
|
67
72
|
}
|
68
73
|
end
|
69
74
|
|
@@ -72,8 +77,8 @@ class Proc
|
|
72
77
|
end
|
73
78
|
|
74
79
|
def serialized_arguments
|
75
|
-
@arguments.
|
76
|
-
|
80
|
+
@arguments.map { |key, value|
|
81
|
+
["$$", key.to_s, serialize_value(value)]
|
77
82
|
}
|
78
83
|
end
|
79
84
|
|
@@ -88,7 +93,7 @@ class Proc
|
|
88
93
|
if value.respond_to?(:serialize)
|
89
94
|
value.serialize
|
90
95
|
else
|
91
|
-
value
|
96
|
+
["%%", value]
|
92
97
|
end
|
93
98
|
end
|
94
99
|
end
|
data/lib/proc/http/client.rb
CHANGED
@@ -5,50 +5,45 @@ require "async/http/internet"
|
|
5
5
|
|
6
6
|
require "protocol/http/body/streamable"
|
7
7
|
|
8
|
+
require "core/async"
|
9
|
+
|
8
10
|
require_relative "request"
|
9
11
|
require_relative "response"
|
10
12
|
|
11
|
-
require_relative "../null_logger"
|
12
|
-
|
13
13
|
class Proc
|
14
14
|
module Http
|
15
15
|
class Client
|
16
|
+
include Is::Async
|
17
|
+
|
16
18
|
def initialize
|
17
19
|
@internet = Async::HTTP::Internet.new
|
18
|
-
@responses = {}
|
19
20
|
end
|
20
21
|
|
21
|
-
def call(method, uri, params: {}, headers: {}, body: nil
|
22
|
+
def call(method, uri, params: {}, headers: {}, body: nil)
|
22
23
|
request = Request.new(method: method, uri: uri, params: params, headers: headers, body: body)
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
await {
|
26
|
+
begin
|
27
|
+
response = make_request(request)
|
28
|
+
|
29
|
+
yield response
|
30
|
+
ensure
|
31
|
+
response&.close
|
32
|
+
end
|
33
|
+
}
|
31
34
|
end
|
32
35
|
|
33
36
|
def close
|
34
|
-
# TODO: Make sure this works. We should also close / clear after accumulating some amount.
|
35
|
-
#
|
36
|
-
@responses.each_value(&:close)
|
37
|
-
@responses.clear
|
38
37
|
@internet.close
|
39
38
|
end
|
40
39
|
|
41
|
-
def count
|
42
|
-
@responses.count
|
43
|
-
end
|
44
|
-
|
45
40
|
private def make_request(request)
|
46
41
|
async_response = @internet.call(*request.callable)
|
47
42
|
wrap_async_response_for_request(async_response, request)
|
48
43
|
end
|
49
44
|
|
50
45
|
private def wrap_async_response_for_request(async_response, request)
|
51
|
-
|
46
|
+
Response.new(request, async_response)
|
52
47
|
end
|
53
48
|
end
|
54
49
|
end
|
data/lib/proc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Powell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-http
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.52.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: core-async
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: oj
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,7 +68,6 @@ files:
|
|
54
68
|
- lib/proc/http/client.rb
|
55
69
|
- lib/proc/http/request.rb
|
56
70
|
- lib/proc/http/response.rb
|
57
|
-
- lib/proc/null_logger.rb
|
58
71
|
- lib/proc/version.rb
|
59
72
|
homepage: https://proc.dev/
|
60
73
|
licenses:
|
@@ -75,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
88
|
- !ruby/object:Gem::Version
|
76
89
|
version: '0'
|
77
90
|
requirements: []
|
78
|
-
rubygems_version: 3.1.
|
91
|
+
rubygems_version: 3.1.4
|
79
92
|
signing_key:
|
80
93
|
specification_version: 4
|
81
94
|
summary: Proc client library.
|