clustered_rpc 0.1.0 → 0.3.1
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/.github/workflows/ruby.yml +51 -0
- data/.travis.yml +10 -1
- data/Gemfile.lock +19 -2
- data/README.md +106 -5
- data/clustered_rpc.gemspec +1 -0
- data/lib/clustered_rpc.rb +20 -6
- data/lib/clustered_rpc/info.rb +9 -6
- data/lib/clustered_rpc/proxy.rb +1 -1
- data/lib/clustered_rpc/transport/redis_cluster.rb +4 -2
- data/lib/clustered_rpc/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 904505b16c185f8541a99935ce6f1e5238069f3f3d69bc95c440d7c7a6669357
|
4
|
+
data.tar.gz: 6557b5bf8f8a58120ab25f70301bf53ef8f7959d57f478b1b0589327a0d1302f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0155fd98b49b9351d9cf4a3086fc9145e1095bc41ff8a2638a800a61ca73a19caefbf43c9a0b9ef458a1e847928077b7b01f5b9da27bf591395f697930fcab8b
|
7
|
+
data.tar.gz: 9facf71c00b00091591e2261e1ccb46e302ee0fa8f3e1d3f9b362305a48c53986a33ba6a797baf07881548261b358d81a95ac050992e49d2e027170aee7f47f7
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ main ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ main ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: [ '2.5', '2.6', '2.7']
|
23
|
+
|
24
|
+
# Service containers to run with `runner-job`
|
25
|
+
services:
|
26
|
+
# Label used to access the service container
|
27
|
+
redis:
|
28
|
+
# Docker Hub image
|
29
|
+
image: redis
|
30
|
+
# Set health checks to wait until redis has started
|
31
|
+
options: >-
|
32
|
+
--health-cmd "redis-cli ping"
|
33
|
+
--health-interval 10s
|
34
|
+
--health-timeout 5s
|
35
|
+
--health-retries 5
|
36
|
+
ports:
|
37
|
+
# Maps port 6379 on service container to the host
|
38
|
+
- 6379:6379
|
39
|
+
|
40
|
+
steps:
|
41
|
+
- uses: actions/checkout@v2
|
42
|
+
- name: Set up Ruby
|
43
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
44
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
45
|
+
# uses: ruby/setup-ruby@v1
|
46
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
47
|
+
with:
|
48
|
+
ruby-version: ${{ matrix.ruby-version }}
|
49
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
50
|
+
- name: Run tests
|
51
|
+
run: bundle exec rake
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
clustered_rpc (0.1
|
4
|
+
clustered_rpc (0.3.1)
|
5
5
|
activesupport
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (6.1.3.
|
10
|
+
activesupport (6.1.3.2)
|
11
11
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
12
12
|
i18n (>= 1.6, < 2)
|
13
13
|
minitest (>= 5.1)
|
@@ -16,14 +16,26 @@ GEM
|
|
16
16
|
awesome_print (1.8.0)
|
17
17
|
byebug (11.1.3)
|
18
18
|
concurrent-ruby (1.1.8)
|
19
|
+
coveralls (0.7.2)
|
20
|
+
multi_json (~> 1.3)
|
21
|
+
rest-client (= 1.6.7)
|
22
|
+
simplecov (>= 0.7)
|
23
|
+
term-ansicolor (= 1.2.2)
|
24
|
+
thor (= 0.18.1)
|
19
25
|
diff-lcs (1.4.4)
|
20
26
|
docile (1.3.2)
|
21
27
|
i18n (1.8.10)
|
22
28
|
concurrent-ruby (~> 1.0)
|
23
29
|
json (2.3.0)
|
30
|
+
mime-types (3.3.1)
|
31
|
+
mime-types-data (~> 3.2015)
|
32
|
+
mime-types-data (3.2021.0225)
|
24
33
|
minitest (5.14.4)
|
34
|
+
multi_json (1.15.0)
|
25
35
|
rake (10.5.0)
|
26
36
|
redis (4.2.2)
|
37
|
+
rest-client (1.6.7)
|
38
|
+
mime-types (>= 1.16)
|
27
39
|
rspec (3.10.0)
|
28
40
|
rspec-core (~> 3.10.0)
|
29
41
|
rspec-expectations (~> 3.10.0)
|
@@ -42,6 +54,10 @@ GEM
|
|
42
54
|
json (>= 1.8, < 3)
|
43
55
|
simplecov-html (~> 0.10.0)
|
44
56
|
simplecov-html (0.10.2)
|
57
|
+
term-ansicolor (1.2.2)
|
58
|
+
tins (~> 0.8)
|
59
|
+
thor (0.18.1)
|
60
|
+
tins (0.13.2)
|
45
61
|
tzinfo (2.0.4)
|
46
62
|
concurrent-ruby (~> 1.0)
|
47
63
|
zeitwerk (2.4.2)
|
@@ -54,6 +70,7 @@ DEPENDENCIES
|
|
54
70
|
bundler (~> 2.0)
|
55
71
|
byebug
|
56
72
|
clustered_rpc!
|
73
|
+
coveralls (>= 0.7.0)
|
57
74
|
rake (~> 10.0)
|
58
75
|
redis
|
59
76
|
rspec (~> 3.0)
|
data/README.md
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
# ClusteredRpc
|
2
|
+
[![RubyGems][gem_version_badge]][ruby_gems]
|
3
|
+
[![Travis CI][travis_ci_badge]][travis_ci]
|
4
|
+
[![Coveralls][coveralls_badge]][coveralls]
|
2
5
|
|
3
|
-
|
6
|
+
_RPC = Remote Procedure Calls_
|
7
|
+
|
8
|
+
ClusteredRpc allows you to run code on every ruby process running within your cluster.
|
9
|
+
|
10
|
+
Clusters are defined using a shared pubsub broker and a common namespace.
|
11
|
+
|
12
|
+
Currently only Redis PubSub is supported by ClusteredRpc.
|
4
13
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
14
|
|
7
15
|
## Installation
|
8
16
|
|
@@ -20,24 +28,110 @@ Or install it yourself as:
|
|
20
28
|
|
21
29
|
$ gem install clustered_rpc
|
22
30
|
|
31
|
+
## Configuration
|
32
|
+
```ruby
|
33
|
+
# Using Redis PubSub
|
34
|
+
ClusteredRpc.config do |c|
|
35
|
+
c.transport_class = ClusteredRpc::Transport::RedisCluster
|
36
|
+
c.cluster_namespace = "myapplication"
|
37
|
+
c.options = {redis_url: "redis://127.0.0.1:6379/3"}
|
38
|
+
end
|
39
|
+
|
40
|
+
```
|
41
|
+
If you are using the same redis server for multiple deployments of your application, then use different namespaces for each.
|
42
|
+
```ruby
|
43
|
+
ClusteredRpc.config do |c|
|
44
|
+
c.transport_class = ClusteredRpc::Transport::RedisCluster
|
45
|
+
# Using the same redis database for the development environment as well...
|
46
|
+
c.cluster_namespace = "myapplication_dev"
|
47
|
+
c.options = {redis_url: "redis://127.0.0.1:6379/3"}
|
48
|
+
end
|
49
|
+
```
|
23
50
|
## Usage
|
24
51
|
|
25
|
-
|
52
|
+
ClusteredRpc allows static (class) methods to be run on every process within the cluster!
|
26
53
|
|
27
54
|
```ruby
|
28
55
|
class MyClass
|
56
|
+
# makes all static-methods available via 'clustered_rpc' proxy method
|
29
57
|
include ClusteredRpc::Methods
|
30
58
|
|
31
59
|
def self.do_the_thing
|
32
60
|
# important code living on many servers in the cluster
|
33
|
-
|
61
|
+
return "I'm important!"
|
34
62
|
end
|
35
63
|
end
|
36
64
|
|
37
65
|
# Run the method on every process running in the cluster
|
66
|
+
# `do_the_thing` is run on each process and the results are returned in a Hash
|
38
67
|
MyClass.clustered_rpc.do_the_thing
|
68
|
+
=> {
|
69
|
+
:request_id => "f030b020e058d7a4",
|
70
|
+
:success => true,
|
71
|
+
:results => {
|
72
|
+
"1ca8a7be5e" => {
|
73
|
+
"seconds" => 3.3e-05,
|
74
|
+
"result" => "I'm important"
|
75
|
+
},
|
76
|
+
"293a7be9ac" => {
|
77
|
+
"seconds" => 4.2e-05,
|
78
|
+
"result" => "I'm important"
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
39
82
|
```
|
83
|
+
The keys in the results Hash (`1ca8a7be5e` and `293a7be9ac`) are the unique instance_ids assigned to each process by ClusteredRpc
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
# Get the stats for your entire cluster
|
87
|
+
ClusteredRpc::Info.clustered_rpc.stats
|
88
|
+
=> {
|
89
|
+
:request_id => "c634e6347b98a0",
|
90
|
+
:success => true,
|
91
|
+
:results => {
|
92
|
+
"ica817be5e" => {
|
93
|
+
:instance_id => "1ca8a7be5e",
|
94
|
+
:transport_class => "ClusteredRpc::Transport::LocalProcess",
|
95
|
+
:options => {},
|
96
|
+
:process_id => 23566,
|
97
|
+
:uptime => "03:14",
|
98
|
+
:used_mb => 35.03,
|
99
|
+
:startup_command => "ruby-2.5.1/bin/rails console",
|
100
|
+
:process_type => "Rails Console",
|
101
|
+
:count_nodes => {}
|
102
|
+
},
|
103
|
+
{
|
104
|
+
:instance_id => "293a7be9ac",
|
105
|
+
:transport_class => "ClusteredRpc::Transport::LocalProcess",
|
106
|
+
:options => {},
|
107
|
+
:process_id => 23736,
|
108
|
+
:uptime => "42:22",
|
109
|
+
:used_mb => 127.69,
|
110
|
+
:startup_command => "ruby-2.5.1/bin/puma",
|
111
|
+
:process_type => "Web Server",
|
112
|
+
:count_nodes => {}
|
113
|
+
}
|
114
|
+
|
115
|
+
}
|
116
|
+
}
|
40
117
|
|
118
|
+
```
|
119
|
+
Of course, methods can be run locally (without `.clustered_rpc`) as well
|
120
|
+
```ruby
|
121
|
+
# Get the stats for the local process
|
122
|
+
ClusteredRpc::Info.stats
|
123
|
+
=> {
|
124
|
+
:instance_id => "1ca8a7be5e",
|
125
|
+
:transport_class => "ClusteredRpc::Transport::LocalProcess",
|
126
|
+
:options => {},
|
127
|
+
:process_id => 23566,
|
128
|
+
:uptime => "00:01",
|
129
|
+
:used_mb => 35.03,
|
130
|
+
:startup_command => "ruby-2.5.1/bin/rails console",
|
131
|
+
:process_type => "Rails Console",
|
132
|
+
:count_nodes => {}
|
133
|
+
}
|
134
|
+
```
|
41
135
|
## Development
|
42
136
|
|
43
137
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -46,8 +140,15 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
46
140
|
|
47
141
|
## Contributing
|
48
142
|
|
49
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
143
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/megalithtracers/clustered_rpc.
|
50
144
|
|
51
145
|
## License
|
52
146
|
|
53
147
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
148
|
+
|
149
|
+
[gem_version_badge]: https://img.shields.io/gem/v/clustered_rpc.svg?style=flat
|
150
|
+
[ruby_gems]: http://rubygems.org/gems/clustered_rpc
|
151
|
+
[travis_ci]: http://travis-ci.org/megalithtracers/clustered_rpc
|
152
|
+
[travis_ci_badge]: https://travis-ci.com/megalithtracers/clustered_rpc.svg?branch=main
|
153
|
+
[coveralls_badge]: https://img.shields.io/coveralls/github/megalithtracers/clustered_rpc/main
|
154
|
+
[coveralls]: https://coveralls.io/github/megalithtracers/clustered_rpc
|
data/clustered_rpc.gemspec
CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency "awesome_print"
|
34
34
|
spec.add_development_dependency "bundler", "~> 2.0"
|
35
35
|
spec.add_development_dependency "byebug"
|
36
|
+
spec.add_development_dependency "coveralls", ">= 0.7.0"
|
36
37
|
spec.add_development_dependency "rake", "~> 10.0"
|
37
38
|
spec.add_development_dependency "redis"
|
38
39
|
spec.add_development_dependency "rspec", "~> 3.0"
|
data/lib/clustered_rpc.rb
CHANGED
@@ -5,12 +5,14 @@ require "json"
|
|
5
5
|
require "active_support/concern"
|
6
6
|
require "clustered_rpc/proxy"
|
7
7
|
require "clustered_rpc/transport/base"
|
8
|
+
require "clustered_rpc/transport/local_process"
|
8
9
|
|
9
10
|
module ClusteredRpc
|
10
11
|
class Error < StandardError; end
|
11
12
|
|
12
13
|
@@instance_id = SecureRandom.hex(5)
|
13
14
|
@@logger = ::Logger.new(STDOUT)
|
15
|
+
@@cluster_namespace = "clustered_rpc"
|
14
16
|
@@transport_class = nil
|
15
17
|
@@transport = nil
|
16
18
|
@@options = {}
|
@@ -21,6 +23,9 @@ module ClusteredRpc
|
|
21
23
|
def self.instance_id=(instance_id); @@instance_id = instance_id; end
|
22
24
|
def self.instance_id; @@instance_id; end
|
23
25
|
|
26
|
+
def self.cluster_namespace=(cluster_namespace); @@cluster_namespace = cluster_namespace; end
|
27
|
+
def self.cluster_namespace; @@cluster_namespace; end
|
28
|
+
|
24
29
|
def self.transport_class=(transport_class); @@transport_class = transport_class; end
|
25
30
|
def self.transport_class; @@transport_class; end
|
26
31
|
|
@@ -29,7 +34,8 @@ module ClusteredRpc
|
|
29
34
|
|
30
35
|
# request_id should have been returned from the call to #cluster_send
|
31
36
|
def self.get_result(request_id, wait_seconds = 1.0)
|
32
|
-
|
37
|
+
# Don't wait at all when using LocalProcess
|
38
|
+
sleep(wait_seconds) if wait_seconds && transport_class != ClusteredRpc::Transport::LocalProcess
|
33
39
|
results = @@transport.get_result(request_id)
|
34
40
|
results.keys.each{|k| results[k] = JSON.parse(results[k])}
|
35
41
|
results # ??? Rails anyone? .with_indifferent_access
|
@@ -38,14 +44,11 @@ module ClusteredRpc
|
|
38
44
|
|
39
45
|
|
40
46
|
def self.config(force=false, &block)
|
47
|
+
@@transport = nil
|
41
48
|
block.call(self)
|
42
|
-
|
43
49
|
@@instance_id ||= SecureRandom.hex(5)
|
44
|
-
|
45
|
-
logger.info "Clustered using #{@@transport_class}"
|
46
|
-
@@transport = @@transport_class.new
|
50
|
+
ensure_transport
|
47
51
|
@@transport.connect
|
48
|
-
|
49
52
|
end
|
50
53
|
|
51
54
|
def self.reconnect
|
@@ -57,9 +60,20 @@ module ClusteredRpc
|
|
57
60
|
def self.publish(payload={})
|
58
61
|
# if :request_id is already present, then we're responding with a process-level response
|
59
62
|
# otherwise we're creating a new clustered_request and should generate a :request_io
|
63
|
+
ensure_transport
|
60
64
|
payload[:request_id] ||= SecureRandom.hex(8)
|
61
65
|
@@transport.publish payload
|
62
66
|
payload[:request_id]
|
63
67
|
end
|
64
68
|
|
69
|
+
private
|
70
|
+
def self.ensure_transport
|
71
|
+
return if @@transport
|
72
|
+
if @@transport_class.nil?
|
73
|
+
require "clustered_rpc/transport/local_process"
|
74
|
+
@@transport_class = ClusteredRpc::Transport::LocalProcess
|
75
|
+
end
|
76
|
+
logger.info "Clustered using #{@@transport_class}[#{@@cluster_namespace}]"
|
77
|
+
@@transport = @@transport_class.new
|
78
|
+
end
|
65
79
|
end
|
data/lib/clustered_rpc/info.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
require '
|
1
|
+
require 'clustered_rpc/methods'
|
2
2
|
require 'open3'
|
3
3
|
|
4
4
|
module ClusteredRpc
|
5
5
|
class Info
|
6
6
|
include ClusteredRpc::Methods
|
7
7
|
|
8
|
-
def self.stats
|
8
|
+
def self.stats(detailed_memory_stats = false)
|
9
9
|
require 'objspace'
|
10
|
+
r =
|
10
11
|
{ instance_id: ClusteredRpc.instance_id,
|
11
12
|
transport_class: ClusteredRpc.transport_class.name.to_s,
|
12
13
|
options: ClusteredRpc.options,
|
@@ -15,11 +16,13 @@ module ClusteredRpc
|
|
15
16
|
used_mb: memory_used,
|
16
17
|
startup_command: startup_command,
|
17
18
|
process_type: lookup_process_type(startup_command),
|
18
|
-
|
19
|
-
gc: GC.stat,
|
20
|
-
count_nodes: ObjectSpace.count_nodes
|
19
|
+
count_nodes: ObjectSpace.count_nodes,
|
21
20
|
}
|
22
|
-
|
21
|
+
if detailed_memory_stats
|
22
|
+
r[:count_objects_size] = ObjectSpace.count_objects_size
|
23
|
+
r[:gc] = GC.stat
|
24
|
+
end
|
25
|
+
r
|
23
26
|
end
|
24
27
|
|
25
28
|
def self.startup_command
|
data/lib/clustered_rpc/proxy.rb
CHANGED
@@ -10,7 +10,7 @@ module ClusteredRpc
|
|
10
10
|
request_id = ::ClusteredRpc.publish({'klass' => @target.name, 'method' => method, 'args' => args, 'kwargs' => kwargs}.merge(@options))
|
11
11
|
{request_id: request_id, success: true, results: ::ClusteredRpc.get_result(request_id, wait_seconds)}
|
12
12
|
rescue => e
|
13
|
-
ClusteredRpc.logger.error "ClusteredRpc::Proxy encountered
|
13
|
+
ClusteredRpc.logger.error "ClusteredRpc::Proxy encountered error: #{e.message}"
|
14
14
|
{request_id: "Error", success: false, results: e.message}
|
15
15
|
end
|
16
16
|
|
@@ -7,14 +7,14 @@ module ClusteredRpc
|
|
7
7
|
def initialize
|
8
8
|
@redis_subscriber = nil
|
9
9
|
@redis_publish = nil
|
10
|
-
@redis_message_pubsub_key = "
|
10
|
+
@redis_message_pubsub_key = "__#{ClusteredRpc.cluster_namespace}_messages"
|
11
11
|
connect
|
12
12
|
end
|
13
13
|
|
14
14
|
def publish(payload={})
|
15
15
|
@redis_publish.publish @redis_message_pubsub_key, payload.to_json
|
16
16
|
rescue => e
|
17
|
-
ClusteredRpc.logger.error "ClusteredRpc.publish encountered
|
17
|
+
ClusteredRpc.logger.error "ClusteredRpc.publish encountered error: #{e.message}"
|
18
18
|
raise e
|
19
19
|
end
|
20
20
|
|
@@ -27,6 +27,8 @@ module ClusteredRpc
|
|
27
27
|
if @subscriber_thread
|
28
28
|
ClusteredRpc.logger.warn "ClusteredRpc: killing subscriber thread"
|
29
29
|
@subscriber_thread.kill
|
30
|
+
# https://stackoverflow.com/questions/49490278/wait-for-a-thread-to-die-in-ruby
|
31
|
+
sleep 0.01 while @subscriber_thread.alive?
|
30
32
|
@redis_subscriber = nil
|
31
33
|
end
|
32
34
|
connect
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clustered_rpc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- megalithtracers@gmail.com
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.7.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.7.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rake
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,6 +144,7 @@ executables: []
|
|
130
144
|
extensions: []
|
131
145
|
extra_rdoc_files: []
|
132
146
|
files:
|
147
|
+
- ".github/workflows/ruby.yml"
|
133
148
|
- ".rspec"
|
134
149
|
- ".travis.yml"
|
135
150
|
- Gemfile
|