qube 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e17e737e738c791b085912c221e278754ffb10108aaf9832a917d554e5400bab
4
+ data.tar.gz: f74e4aa68c5f4d8cecbb2ec8b8e85ef59c25beb03b4e85470ee711052c42ae75
5
+ SHA512:
6
+ metadata.gz: 3c28608fb8d3069dbe6549387772356cb8df2dbd030d48d5b236a2fc19fccc785a1da8d2bc8dc9c7f772aa1bfb55cc8eda1ee80e38f11f88818ed62b638f8b4a
7
+ data.tar.gz: 9d0fca0029be9543b39fb917a0f80f7b011e9dced574e98438c3fe90d9a0b4730b75ea50398e99d9dd8921c818b65a055bd7032f9e83fa235cab7473bc09b5c3
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /lua/.rocks
10
+ /lua/*.snap
11
+ /lua/*.xlog
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.2
6
+ before_install: gem install bundler -v 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 tnt-qube
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # qube-ruby
2
+
3
+ Сlient for the Tarantool [Queue](https://github.com/tarantool/queue) for Ruby over HTTP via persistent connection. Currently supported is `take`, `put`, `ack` and will continue to add as needed.
4
+
5
+ ```ruby
6
+ require 'qube'
7
+
8
+ Qube.setup do |c|
9
+ c.api_uri = 'http://localhost:5672/api/v1/'
10
+ c.api_token = '77c04ced3f915240d0c5d8d5819f84c7' # md5 -s qube
11
+ end
12
+
13
+ queue = Qube::Queue.new
14
+ pp queue.tube_exist?('welcome_mail') # => false
15
+
16
+ tube = queue.create_tube(name: 'welcome_mail', type: 'fifo')
17
+ pp tube # => #<Qube::Tube:0x00007fe68b159b80 ...
18
+
19
+ put_status = tube.put({ name: 'Ivan Ivanov', locale: 'ru', email: 'ivan@localhost.dev' })
20
+ pp put_status # => true
21
+
22
+ task = tube.take
23
+ pp task
24
+ # =>
25
+ # {
26
+ # "task_id" => 0,
27
+ # "data" => {
28
+ # "email" => "ivan@localhost.dev",
29
+ # "name" => "Ivan Ivanov",
30
+ # "locale" => "ru"
31
+ # }
32
+ # }
33
+
34
+ ack_status = tube.ack task.dig('task_id')
35
+ pp ack_status
36
+ # => true
37
+
38
+ # Taking the each task, processing and ack it in the one step
39
+ tube.each_task do |task|
40
+ pp task
41
+ end
42
+
43
+ delete_status = queue.delete_tube('welcome_mail')
44
+ pp delete_status
45
+ # => true
46
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "qube"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/case/base.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'qube'
2
+
3
+ Qube.setup do |c|
4
+ c.api_uri = 'http://localhost:5672/api/v1/'
5
+ c.api_token = '77c04ced3f915240d0c5d8d5819f84c7' # md5 -s qube
6
+ end
7
+
8
+ queue = Qube::Queue.new
9
+ pp queue.tube_exist?('welcome_mail') # => false
10
+
11
+ tube = queue.create_tube(name: 'welcome_mail', type: 'fifo')
12
+ pp tube # => #<Qube::Tube:0x00007fe68b159b80 ...
13
+
14
+ put_status = tube.put({ name: 'Ivan Ivanov', locale: 'ru', email: 'ivan@localhost.dev' })
15
+ pp put_status # => true
16
+
17
+ task = tube.take
18
+ pp task
19
+ # =>
20
+ # {
21
+ # "task_id" => 0,
22
+ # "data" => {
23
+ # "email" => "ivan@localhost.dev",
24
+ # "name" => "Ivan Ivanov",
25
+ # "locale" => "ru"
26
+ # }
27
+ # }
28
+
29
+ ack_status = tube.ack(task.dig('task_id'))
30
+ pp ack_status
31
+ # => true
32
+
33
+ # Taking the each task, processing it and ack
34
+ tube.each_task do |task|
35
+ pp task
36
+ end
37
+
38
+ delete_status = queue.delete_tube('welcome_mail')
39
+ pp delete_status
40
+ # => true
41
+
data/lib/qube.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'qube/config'
2
+ require 'qube/transport/http'
3
+ require 'qube/transport/client'
4
+ require 'qube/model/queue'
5
+ require 'qube/model/tube'
@@ -0,0 +1,38 @@
1
+ require 'logger'
2
+ require 'securerandom'
3
+
4
+ module Qube
5
+ class << self
6
+ attr_accessor :config
7
+ end
8
+
9
+ def self.setup
10
+ self.config ||= Config.new
11
+ yield config
12
+ end
13
+
14
+ class Config
15
+ attr_accessor :api_uri
16
+ attr_accessor :api_token
17
+ attr_accessor :pool_size
18
+ attr_accessor :timeout
19
+ attr_accessor :user_agent
20
+ attr_accessor :logger
21
+ attr_accessor :logger_level
22
+ attr_accessor :http_debug
23
+ attr_accessor :session
24
+
25
+ def initialize
26
+ @api_uri = ENV['QUBE_API_URI'] || 'http://localhost:9191/qube/api/v1'
27
+ @api_token = ENV['QUBE_API_TOKEN'] || '77c04ced3f915240d0c5d8d5819f84c7' # bash: md5 -s qube
28
+ @pool_size = 5
29
+ @timeout = 2
30
+ @user_agent = "QubeRubyClient/#{Qube::VERSION}"
31
+ @logger_level = :debug
32
+ @logger = ::Logger.new STDOUT
33
+ @logger.level = @logger_level
34
+ @http_debug = true
35
+ @session = SecureRandom.uuid
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,36 @@
1
+ require 'securerandom'
2
+
3
+ module Qube
4
+ class Queue
5
+ attr_reader :tubes
6
+ attr_reader :statistics
7
+
8
+ def initialize
9
+ @config = Qube.config
10
+ @client = Client.new
11
+ @tubes = nil
12
+ @statistics = nil
13
+ end
14
+
15
+ def statistics
16
+ @statistics ||= @client.get('statistics')&.body
17
+ end
18
+
19
+ def tubes
20
+ @tubes ||= @client.get('tubes')&.body
21
+ end
22
+
23
+ def create_tube(options = {})
24
+ Tube.new(options)
25
+ end
26
+
27
+ def tube_exist?(name)
28
+ tubes.include?(name)
29
+ end
30
+
31
+ def delete_tube(name)
32
+ @client.delete("tubes/#{name}")&.body
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,57 @@
1
+ module Qube
2
+ class Tube
3
+ attr_reader :name
4
+
5
+ def initialize(options = {})
6
+ @config = Qube.config
7
+ @client = Client.new
8
+ @name = options.delete(:name)
9
+ @type = options.delete(:type)
10
+ @options = options.merge!(if_not_exists: true)
11
+ fetch_or_create_tube
12
+ end
13
+
14
+ # POST tubes/:name
15
+ def put(task, options = {})
16
+ response = @client.post("tubes/#{@name}", tube: @name, task: task, options: options)
17
+ response.code == 200
18
+ end
19
+
20
+ # GET tubes/:name
21
+ def take(timeout = 0)
22
+ @client.get("tubes/#{@name}", timeout: timeout)&.body
23
+ end
24
+
25
+ # PUT tubes/:name/:task_id/ask
26
+ def ack(data)
27
+ task_id = data.is_a?(Hash) ? data.dig('task_id') : data
28
+ response = @client.put("tubes/#{@name}/#{task_id}/ack", tube: @name, task_id: task_id)
29
+ response.code == 200
30
+ end
31
+
32
+ # DELETE tubes/:name
33
+ def drop
34
+ response = @client.delete("tubes/#{@name}")
35
+ response.code == 200
36
+ end
37
+
38
+ def each_task(timeout = 0)
39
+ loop do
40
+ task = take(timeout)
41
+ if task.nil? || task.empty?
42
+ break
43
+ else
44
+ yield task
45
+ ack(task)
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def fetch_or_create_tube
53
+ response = @client.post('tubes', tube: @name, type: @type, options: @options.compact)
54
+ self if response.code == 200
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,12 @@
1
+ module Qube
2
+ # Just wrapper, need for the future work
3
+ class Client
4
+ def initialize
5
+ @transport = Qube::HTTP.new
6
+ end
7
+
8
+ def method_missing(m, *args)
9
+ @transport.send(m, *args)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,73 @@
1
+ require 'uri'
2
+ require 'json'
3
+ require 'net/http'
4
+ require 'net/http/persistent'
5
+
6
+ module Qube
7
+ class HTTP
8
+
9
+ VERBS = {
10
+ get: Net::HTTP::Get,
11
+ post: Net::HTTP::Post,
12
+ put: Net::HTTP::Put,
13
+ delete: Net::HTTP::Delete
14
+ }
15
+
16
+ Response = Struct.new(:code, :body)
17
+
18
+ def initialize
19
+ @config = Qube.config
20
+ @connection = Net::HTTP::Persistent.new
21
+
22
+ @api_uri = @config.api_uri
23
+ @api_token = @config.api_token
24
+ @user_agent = @config.user_agent
25
+ @logger = @config.logger
26
+ end
27
+
28
+ def base_headers
29
+ {
30
+ 'X-Auth-Token' => @api_token,
31
+ 'User-Agent' => @user_agent,
32
+ 'Content-Type' => 'application/json'
33
+ }
34
+ end
35
+
36
+ def get(path, options = {})
37
+ execute(path, :get, options)
38
+ end
39
+
40
+ def post(path, options = {})
41
+ execute(path, :post, options)
42
+ end
43
+
44
+ def put(path, options = {})
45
+ execute(path, :put, options)
46
+ end
47
+
48
+ def delete(path, options = {})
49
+ execute(path, :delete, options)
50
+ end
51
+
52
+ private
53
+ def execute(path, method, options = {})
54
+ url = URI.join(@api_uri, path)
55
+ req = VERBS[method].new(url.request_uri)
56
+
57
+ # Build headers and body
58
+ options.transform_keys!(&:to_s) unless options.empty?
59
+ headers = base_headers.merge(options.dig('headers') || options)
60
+ headers.each{ |k,v| req[k] = v }
61
+ req.body = (options.dig('body') || options || {}).to_json
62
+
63
+ # Send request and process response
64
+ resp = @connection.request(url.to_s, req)
65
+ body = resp.body.empty? ? {} : JSON.parse(resp.body)
66
+ Response.new(resp.code.to_i, body)
67
+
68
+ rescue => e
69
+ @logger.error(e.message) if @logger
70
+ raise e
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module Qube
2
+ VERSION = "0.0.1"
3
+ end
data/qube.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ require_relative 'lib/qube/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'qube'
5
+ spec.version = Qube::VERSION
6
+ spec.authors = ["Sergey Fedorov"]
7
+ spec.email = ["creadone@gmail.com"]
8
+
9
+ spec.summary = %q{Tarantool Queue client for Ruby}
10
+ spec.description = %q{Ruby HTTP-client for the Message Queue based on Tarantool}
11
+ spec.homepage = "https://github.com/tnt-qube/qube-ruby"
12
+
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
15
+
16
+ spec.add_runtime_dependency 'net-http-persistent', '~> 3.1.0'
17
+
18
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+
22
+ spec.require_paths = ["lib"]
23
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qube
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sergey Fedorov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-http-persistent
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.0
27
+ description: Ruby HTTP-client for the Message Queue based on Tarantool
28
+ email:
29
+ - creadone@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".travis.yml"
36
+ - LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - bin/console
40
+ - bin/setup
41
+ - case/base.rb
42
+ - lib/qube.rb
43
+ - lib/qube/config.rb
44
+ - lib/qube/model/queue.rb
45
+ - lib/qube/model/tube.rb
46
+ - lib/qube/transport/client.rb
47
+ - lib/qube/transport/http.rb
48
+ - lib/qube/version.rb
49
+ - qube.gemspec
50
+ homepage: https://github.com/tnt-qube/qube-ruby
51
+ licenses:
52
+ - MIT
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.7.0
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.1.4
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Tarantool Queue client for Ruby
73
+ test_files: []