arthropod 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +49 -0
- data/README.md +92 -0
- data/Rakefile +11 -0
- data/arthropod.gemspec +27 -0
- data/examples/client.rb +8 -0
- data/examples/server.rb +9 -0
- data/lib/arthropod.rb +4 -0
- data/lib/arthropod/client.rb +34 -0
- data/lib/arthropod/request.rb +43 -0
- data/lib/arthropod/response.rb +24 -0
- data/lib/arthropod/server.rb +20 -0
- data/lib/arthropod/version.rb +3 -0
- data/spec/client_spec.rb +67 -0
- data/spec/server_spec.rb +51 -0
- data/spec/spec_helper.rb +100 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 402aefa5ebb2883aa9660285c850995454a8a5dd87dc5cf4b1fc3131c66a25cc
|
4
|
+
data.tar.gz: fb12c70b9088b22e81cac21de40edd01e23fb50b668b8f775010ed80cfdff31b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2bf3436d18735c33198c163fc950aaca20f663828c6e5cdc918000df26bcf109a1c6abac885c1a96dec22fc42c8a4d0ea64c745165974d3b0a75d4738ed81364
|
7
|
+
data.tar.gz: 52a1c6f6b0455633e97414eae5eeadf359b4436aae49653714031f9aba8f023538845c77fc9c9536426a5c749073c99aae67db1225345ee793b3916eb23467d1
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.env
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
arthropod (0.0.1)
|
5
|
+
aws-sdk-sqs
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
aws-eventstream (1.0.3)
|
11
|
+
aws-partitions (1.251.0)
|
12
|
+
aws-sdk-core (3.84.0)
|
13
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
14
|
+
aws-partitions (~> 1, >= 1.239.0)
|
15
|
+
aws-sigv4 (~> 1.1)
|
16
|
+
jmespath (~> 1.0)
|
17
|
+
aws-sdk-sqs (1.23.1)
|
18
|
+
aws-sdk-core (~> 3, >= 3.71.0)
|
19
|
+
aws-sigv4 (~> 1.1)
|
20
|
+
aws-sigv4 (1.1.0)
|
21
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
22
|
+
diff-lcs (1.3)
|
23
|
+
jmespath (1.4.0)
|
24
|
+
rake (13.0.1)
|
25
|
+
rspec (3.9.0)
|
26
|
+
rspec-core (~> 3.9.0)
|
27
|
+
rspec-expectations (~> 3.9.0)
|
28
|
+
rspec-mocks (~> 3.9.0)
|
29
|
+
rspec-core (3.9.0)
|
30
|
+
rspec-support (~> 3.9.0)
|
31
|
+
rspec-expectations (3.9.0)
|
32
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
33
|
+
rspec-support (~> 3.9.0)
|
34
|
+
rspec-mocks (3.9.0)
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
+
rspec-support (~> 3.9.0)
|
37
|
+
rspec-support (3.9.0)
|
38
|
+
|
39
|
+
PLATFORMS
|
40
|
+
ruby
|
41
|
+
|
42
|
+
DEPENDENCIES
|
43
|
+
arthropod!
|
44
|
+
bundler
|
45
|
+
rake
|
46
|
+
rspec
|
47
|
+
|
48
|
+
BUNDLED WITH
|
49
|
+
2.0.2
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Arthropod
|
2
|
+
|
3
|
+
Arthropod is a easy way to run remote ruby code synchronously, using Amazon SQS.
|
4
|
+
|
5
|
+
*Do not use it yet, the API isn't stable at all and it wasn't tested enough on production*
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
A simple use case first, let's say you want to push a video encoding task to another server:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
url_of_the_video = "https://my_storage.my_service.com/my_video_file.mp4"
|
13
|
+
response = Arthropod::Client.push(queue_name: "video_encoding", body: { url: url_of_the_video })
|
14
|
+
|
15
|
+
puts response.body
|
16
|
+
# => "https://my_storage.my_service.com/my_reencoded_video_file.mp4"
|
17
|
+
```
|
18
|
+
|
19
|
+
On the "server" side:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
Arthropod::Server.pull(queue_name: "video_encoding") do |request|
|
23
|
+
video_url = request.body.url
|
24
|
+
|
25
|
+
# Do the encoding stuff
|
26
|
+
encoded_video_url = VideoEncoder.encode(video_url)
|
27
|
+
|
28
|
+
encoded_video_url # Everything evaluated here will be sent back to the client
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
As you see, it's all synchronous and, since SQS will save your messages until they are consumed, your server doesn't even have to be listening right when you push the task (more on that later).
|
33
|
+
|
34
|
+
It is also possible to push updates from the server:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Arthropod::Server.pull(queue_name: "video_encoding") do |request|
|
38
|
+
video_url = request.body.url
|
39
|
+
|
40
|
+
# Do the encoding stuff but this time the VideoEncoder class will give you a percentage of completion
|
41
|
+
VideoEncoder.encode(video_url) do |percentage_of_completion|
|
42
|
+
request.respond { percentage_of_completion: percentage_of_completion }
|
43
|
+
end
|
44
|
+
|
45
|
+
encoded_video_url # Everything evaluated here will be sent back to the client
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
And on the client side:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
url_of_the_video = "https://my_storage.my_service.com/my_video_file.mp4"
|
53
|
+
response = Arthropod::Client.push(queue_name: "video_encoding", body: { url: url_of_the_video }) do |response|
|
54
|
+
puts response.body.percentage_of_completion # => 10, 20, 30, etc
|
55
|
+
end
|
56
|
+
|
57
|
+
puts response.body
|
58
|
+
# => "https://my_storage.my_service.com/my_reencoded_video_file.mp4"
|
59
|
+
```
|
60
|
+
|
61
|
+
## API
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
response = Arthropod::Client.push(queue_name: "video_encoding", body: { url: url_of_the_video }) do |response|
|
65
|
+
puts response.body
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
This method pushes a job to the SQS queue `queue_name` and waits for the job completion, a block can be optionally provided if you expect the server to send you some updates along the way. The return value is the last value evaluated in the server block.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Arthropod::Server.pull(queue_name: "video_encoding") do |request|
|
73
|
+
request.respond "some_update"
|
74
|
+
|
75
|
+
"final_result"
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
This method will take a job from the queue and give it to the block, if no job are available the method will return immediately, it's your responsiblity to put this call in the loop if you want to. The last value from the block will be sent back to the client.
|
80
|
+
|
81
|
+
## Why would you do take an asynchronous thing and make it synchronous?
|
82
|
+
|
83
|
+
This library is here to solve a few real use-cases we encoutered, most of them involves running heavy tasks on remote servers or on remote computers that are not accessible through the internet. For example:
|
84
|
+
|
85
|
+
* running some CUDA-related stuff from a cheap server, sometimes it's way cheaper to have a pretty beefy computers in house and run your heavy tasks on them instead of renting one for several hundred dollars each month.
|
86
|
+
* sometimes you need to access some data that are only accessible locally, thing about 3D rendering where your assets, cache, etc are all stored locally for better performance. Now your local computer can pull tasks from the SQS queue, run them and push the results.
|
87
|
+
|
88
|
+
Of course you can also achieve that by simply using SQS or any kind of message system, what Arthropod does is just to make it easier, however it's your responsibilty to run it in an asynchronous environment, think about an ActiveJob task for example. At its core Arthropod is just a thin layer around SQS.
|
89
|
+
|
90
|
+
## Example: the poor man's video encoding service
|
91
|
+
|
92
|
+
If you're not concerned about latency, you can for example push some heavy video encoding task from and ActiveJob job in your Rails task and run a little cron job every minute on your uber-CUDA-powered computer at home to pull those jobs and reencode your videos. It should be reliable enough and it may be even be way faster than doing it with the CPU off a regular server.
|
data/Rakefile
ADDED
data/arthropod.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "arthropod/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = "arthropod"
|
9
|
+
gem.version = Arthropod::VERSION
|
10
|
+
gem.authors = ["Victor Goya"]
|
11
|
+
gem.email = ["goya.victor@gmail.com"]
|
12
|
+
gem.description = "Easy remote task execution with SQS"
|
13
|
+
gem.summary = "Execute ruby task on another server synchronously using Amazon SQS"
|
14
|
+
|
15
|
+
gem.files = `git ls-files -z`.split("\x0")
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
|
18
|
+
gem.licenses = ["MIT"]
|
19
|
+
|
20
|
+
gem.add_dependency 'aws-sdk-sqs'
|
21
|
+
|
22
|
+
gem.required_ruby_version = "~> 2.0"
|
23
|
+
|
24
|
+
gem.add_development_dependency 'bundler'
|
25
|
+
gem.add_development_dependency 'rspec'
|
26
|
+
gem.add_development_dependency 'rake'
|
27
|
+
end
|
data/examples/client.rb
ADDED
data/examples/server.rb
ADDED
data/lib/arthropod.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'aws-sdk-sqs'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module Arthropod
|
5
|
+
module Client
|
6
|
+
def self.push(queue_name:, body:, client: nil)
|
7
|
+
client ||= Aws::SQS::Client.new
|
8
|
+
|
9
|
+
sender_queue = client.create_queue(queue_name: queue_name)
|
10
|
+
return_queue = client.create_queue(queue_name: SecureRandom.uuid.gsub("-", "_"))
|
11
|
+
|
12
|
+
# Send our order with a return queue so we can get responses
|
13
|
+
client.send_message(queue_url: sender_queue.queue_url, message_body: JSON.dump({ return_queue_url: return_queue.queue_url, body: body }))
|
14
|
+
|
15
|
+
loop do
|
16
|
+
response = client.receive_message(queue_url: return_queue.queue_url, max_number_of_messages: 1, wait_time_seconds: 1)
|
17
|
+
response.messages.each do |message|
|
18
|
+
response = Arthropod::Response.new(client: client, message: message)
|
19
|
+
begin
|
20
|
+
if response.state == "close"
|
21
|
+
return response
|
22
|
+
else
|
23
|
+
yield response if block_given?
|
24
|
+
end
|
25
|
+
ensure
|
26
|
+
client.delete_message(queue_url: return_queue.queue_url, receipt_handle: message.receipt_handle)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
ensure
|
31
|
+
client.delete_queue(queue_url: return_queue.queue_url) if return_queue
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Arthropod
|
2
|
+
class Request
|
3
|
+
attr_reader :message, :client
|
4
|
+
|
5
|
+
def initialize(client:, message:)
|
6
|
+
@client = client
|
7
|
+
@message = message
|
8
|
+
end
|
9
|
+
|
10
|
+
def body
|
11
|
+
parsed_message_body["body"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def return_queue_url
|
15
|
+
parsed_message_body["return_queue_url"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def state
|
19
|
+
parsed_message_body["state"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond(body = nil)
|
23
|
+
send_message({ state: "open", body: body })
|
24
|
+
end
|
25
|
+
|
26
|
+
def close(body = nil)
|
27
|
+
send_message({ state: "close", body: body })
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def send_message(message_body)
|
33
|
+
client.send_message({
|
34
|
+
queue_url: return_queue_url,
|
35
|
+
message_body: JSON.dump(message_body)
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
def parsed_message_body
|
40
|
+
@parsed_message_body ||= JSON.parse(message.body)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Arthropod
|
2
|
+
class Response
|
3
|
+
attr_reader :message, :client
|
4
|
+
|
5
|
+
def initialize(client:, message:)
|
6
|
+
@client = client
|
7
|
+
@message = message
|
8
|
+
end
|
9
|
+
|
10
|
+
def body
|
11
|
+
parsed_message_body["body"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def state
|
15
|
+
parsed_message_body["state"]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def parsed_message_body
|
21
|
+
@parsed_message_body ||= JSON.parse(message.body)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'aws-sdk-sqs'
|
2
|
+
|
3
|
+
module Arthropod
|
4
|
+
module Server
|
5
|
+
def self.pull(queue_name:, client: nil)
|
6
|
+
client ||= Aws::SQS::Client.new
|
7
|
+
|
8
|
+
sender_queue = client.create_queue(queue_name: queue_name)
|
9
|
+
response = client.receive_message(queue_url: sender_queue.queue_url, max_number_of_messages: 1, wait_time_seconds: 1)
|
10
|
+
response.messages.each do |message|
|
11
|
+
request = Arthropod::Request.new(client: client, message: message)
|
12
|
+
begin
|
13
|
+
request.close(yield request)
|
14
|
+
ensure
|
15
|
+
client.delete_message(queue_url: sender_queue.queue_url, receipt_handle: message.receipt_handle)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'arthropod'
|
2
|
+
|
3
|
+
RSpec.describe(Arthropod::Client) do
|
4
|
+
context "#push" do
|
5
|
+
let(:client) do
|
6
|
+
Aws::SQS::Client.new(stub_responses: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:sender_queue_url) do
|
10
|
+
"https://aws.com/sender_queue_url"
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:return_queue_url) do
|
14
|
+
"https://aws.com/return_queue_url"
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:body) do
|
18
|
+
{ my_key: "my_value" }
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:uuid) do
|
22
|
+
"444444444444-4444-4444-8888-88888888"
|
23
|
+
end
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
expect(SecureRandom).to(
|
27
|
+
receive(:uuid)
|
28
|
+
.and_return(uuid)
|
29
|
+
)
|
30
|
+
expect(client).to(
|
31
|
+
receive(:create_queue)
|
32
|
+
.with({ queue_name: "test" })
|
33
|
+
.and_return(OpenStruct.new(queue_url: sender_queue_url))
|
34
|
+
)
|
35
|
+
expect(client).to(
|
36
|
+
receive(:create_queue)
|
37
|
+
.with({ queue_name: uuid.gsub("-", "_") })
|
38
|
+
.and_return(OpenStruct.new(queue_url: return_queue_url))
|
39
|
+
)
|
40
|
+
expect(client).to(
|
41
|
+
receive(:send_message)
|
42
|
+
.with({ queue_url: sender_queue_url, message_body: JSON.dump({ return_queue_url: return_queue_url, body: body }) })
|
43
|
+
)
|
44
|
+
expect(client).to(
|
45
|
+
receive(:receive_message)
|
46
|
+
.with({ queue_url: return_queue_url, max_number_of_messages: 1, wait_time_seconds: 1 })
|
47
|
+
.and_return(OpenStruct.new(messages: [ OpenStruct.new({ "body" => JSON.dump({ "state" => "open", "body" => "update" }), receipt_handle: "receipt_handle" }) ]))
|
48
|
+
)
|
49
|
+
expect(client).to(
|
50
|
+
receive(:receive_message)
|
51
|
+
.with({ queue_url: return_queue_url, max_number_of_messages: 1, wait_time_seconds: 1 })
|
52
|
+
.and_return(OpenStruct.new(messages: [ OpenStruct.new({ "body" => JSON.dump({ "state" => "close", "body" => "payload" }), receipt_handle: "receipt_handle" }) ]))
|
53
|
+
)
|
54
|
+
expect(client).to(
|
55
|
+
receive(:delete_queue)
|
56
|
+
.with({ queue_url: return_queue_url })
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "works" do
|
61
|
+
response = Arthropod::Client.push(client: client, queue_name: "test", body: body) do |response|
|
62
|
+
expect(response.body).to eq("update")
|
63
|
+
end
|
64
|
+
expect(response.body).to eq("payload")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'arthropod'
|
2
|
+
|
3
|
+
RSpec.describe(Arthropod::Server) do
|
4
|
+
context "#pull" do
|
5
|
+
let(:client) do
|
6
|
+
Aws::SQS::Client.new(stub_responses: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:sender_queue_url) do
|
10
|
+
"https://aws.com/sender_queue_url"
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:return_queue_url) do
|
14
|
+
"https://aws.com/return_queue_url"
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:uuid) do
|
18
|
+
"444444444444-4444-4444-8888-88888888"
|
19
|
+
end
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
expect(client).to(
|
23
|
+
receive(:create_queue)
|
24
|
+
.with({ queue_name: "test" })
|
25
|
+
.and_return(OpenStruct.new(queue_url: sender_queue_url))
|
26
|
+
)
|
27
|
+
expect(client).to(
|
28
|
+
receive(:receive_message)
|
29
|
+
.with({ queue_url: sender_queue_url, max_number_of_messages: 1, wait_time_seconds: 1 })
|
30
|
+
.and_return(OpenStruct.new(messages: [ OpenStruct.new({ "body" => JSON.dump({ "body" => "request", "return_queue_url" => return_queue_url }), receipt_handle: "receipt_handle" }) ]))
|
31
|
+
)
|
32
|
+
expect(client).to(
|
33
|
+
receive(:send_message)
|
34
|
+
.with({ queue_url: return_queue_url, message_body: JSON.dump({ state: "open", body: "response" }) })
|
35
|
+
)
|
36
|
+
expect(client).to(
|
37
|
+
receive(:send_message)
|
38
|
+
.with({ queue_url: return_queue_url, message_body: JSON.dump({ state: "close", body: "final_response" }) })
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "works" do
|
43
|
+
Arthropod::Server.pull(client: client, queue_name: "test") do |request|
|
44
|
+
expect(request.body).to eq("request")
|
45
|
+
request.respond "response"
|
46
|
+
|
47
|
+
"final_response"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
16
|
+
RSpec.configure do |config|
|
17
|
+
# rspec-expectations config goes here. You can use an alternate
|
18
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
19
|
+
# assertions if you prefer.
|
20
|
+
config.expect_with :rspec do |expectations|
|
21
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
22
|
+
# and `failure_message` of custom matchers include text for helper methods
|
23
|
+
# defined using `chain`, e.g.:
|
24
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
25
|
+
# # => "be bigger than 2 and smaller than 4"
|
26
|
+
# ...rather than:
|
27
|
+
# # => "be bigger than 2"
|
28
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
29
|
+
end
|
30
|
+
|
31
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
32
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
33
|
+
config.mock_with :rspec do |mocks|
|
34
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
35
|
+
# a real object. This is generally recommended, and will default to
|
36
|
+
# `true` in RSpec 4.
|
37
|
+
mocks.verify_partial_doubles = true
|
38
|
+
end
|
39
|
+
|
40
|
+
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
41
|
+
# have no way to turn it off -- the option exists only for backwards
|
42
|
+
# compatibility in RSpec 3). It causes shared context metadata to be
|
43
|
+
# inherited by the metadata hash of host groups and examples, rather than
|
44
|
+
# triggering implicit auto-inclusion in groups with matching metadata.
|
45
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
46
|
+
|
47
|
+
# The settings below are suggested to provide a good initial experience
|
48
|
+
# with RSpec, but feel free to customize to your heart's content.
|
49
|
+
=begin
|
50
|
+
# This allows you to limit a spec run to individual examples or groups
|
51
|
+
# you care about by tagging them with `:focus` metadata. When nothing
|
52
|
+
# is tagged with `:focus`, all examples get run. RSpec also provides
|
53
|
+
# aliases for `it`, `describe`, and `context` that include `:focus`
|
54
|
+
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
55
|
+
config.filter_run_when_matching :focus
|
56
|
+
|
57
|
+
# Allows RSpec to persist some state between runs in order to support
|
58
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
59
|
+
# you configure your source control system to ignore this file.
|
60
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
61
|
+
|
62
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
63
|
+
# recommended. For more details, see:
|
64
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
65
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
66
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
67
|
+
config.disable_monkey_patching!
|
68
|
+
|
69
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
70
|
+
# be too noisy due to issues in dependencies.
|
71
|
+
config.warnings = true
|
72
|
+
|
73
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
74
|
+
# file, and it's useful to allow more verbose output when running an
|
75
|
+
# individual spec file.
|
76
|
+
if config.files_to_run.one?
|
77
|
+
# Use the documentation formatter for detailed output,
|
78
|
+
# unless a formatter has already been configured
|
79
|
+
# (e.g. via a command-line flag).
|
80
|
+
config.default_formatter = "doc"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Print the 10 slowest examples and example groups at the
|
84
|
+
# end of the spec run, to help surface which specs are running
|
85
|
+
# particularly slow.
|
86
|
+
config.profile_examples = 10
|
87
|
+
|
88
|
+
# Run specs in random order to surface order dependencies. If you find an
|
89
|
+
# order dependency and want to debug it, you can fix the order by providing
|
90
|
+
# the seed, which is printed after each run.
|
91
|
+
# --seed 1234
|
92
|
+
config.order = :random
|
93
|
+
|
94
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
95
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
96
|
+
# test failures related to randomization by passing the same `--seed` value
|
97
|
+
# as the one that triggered the failure.
|
98
|
+
Kernel.srand config.seed
|
99
|
+
=end
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arthropod
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Victor Goya
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-sqs
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Easy remote task execution with SQS
|
70
|
+
email:
|
71
|
+
- goya.victor@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- arthropod.gemspec
|
83
|
+
- examples/client.rb
|
84
|
+
- examples/server.rb
|
85
|
+
- lib/arthropod.rb
|
86
|
+
- lib/arthropod/client.rb
|
87
|
+
- lib/arthropod/request.rb
|
88
|
+
- lib/arthropod/response.rb
|
89
|
+
- lib/arthropod/server.rb
|
90
|
+
- lib/arthropod/version.rb
|
91
|
+
- spec/client_spec.rb
|
92
|
+
- spec/server_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
94
|
+
homepage:
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '2.0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubygems_version: 3.0.3
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Execute ruby task on another server synchronously using Amazon SQS
|
117
|
+
test_files: []
|