qube 0.0.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 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: []