sevak 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +68 -0
- data/Guardfile +42 -0
- data/LICENSE.txt +1 -0
- data/README.md +37 -0
- data/Rakefile +85 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/chillr_sevak.gemspec +24 -0
- data/config/default.yml.example +5 -0
- data/lib/sevak.rb +110 -0
- data/lib/sevak/consumer.rb +98 -0
- data/lib/sevak/core.rb +11 -0
- data/lib/sevak/publisher.rb +16 -0
- data/lib/sevak/version.rb +3 -0
- data/tasks/.keep +0 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 255061d49d7c114c2635cf303f0741b632001222
|
4
|
+
data.tar.gz: 72ed6a68f4979c751ff3116c091c397c6b3b7e79
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7572555dc028728c8460d1a3304124cfb548d45e171c9325bd080df76263ee186aaf01042eb22aeb7c4b85aa41680b5c0ea85e6d187d40fe0aaf8481a80c732d
|
7
|
+
data.tar.gz: 88fd6c8ece0a9c02216d19f561e87bd01b2726c112b78ee3955b125feff70bf565d480733f9b2bceeb785100e331a5ea96ad64081b081bddb8f5b9954d89594c
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sevak (0.2.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
amq-protocol (2.2.0)
|
10
|
+
bunny (2.7.0)
|
11
|
+
amq-protocol (>= 2.2.0)
|
12
|
+
coderay (1.1.2)
|
13
|
+
ffi (1.9.18)
|
14
|
+
formatador (0.2.5)
|
15
|
+
guard (2.14.1)
|
16
|
+
formatador (>= 0.2.4)
|
17
|
+
listen (>= 2.7, < 4.0)
|
18
|
+
lumberjack (~> 1.0)
|
19
|
+
nenv (~> 0.1)
|
20
|
+
notiffany (~> 0.0)
|
21
|
+
pry (>= 0.9.12)
|
22
|
+
shellany (~> 0.0)
|
23
|
+
thor (>= 0.18.1)
|
24
|
+
guard-compat (1.2.1)
|
25
|
+
guard-minitest (2.4.6)
|
26
|
+
guard-compat (~> 1.2)
|
27
|
+
minitest (>= 3.0)
|
28
|
+
highline (1.7.8)
|
29
|
+
listen (3.1.5)
|
30
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
31
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
32
|
+
ruby_dep (~> 1.2)
|
33
|
+
lumberjack (1.0.12)
|
34
|
+
metaclass (0.0.4)
|
35
|
+
method_source (0.8.2)
|
36
|
+
minitest (5.10.3)
|
37
|
+
mocha (1.3.0)
|
38
|
+
metaclass (~> 0.0.1)
|
39
|
+
nenv (0.3.0)
|
40
|
+
notiffany (0.1.1)
|
41
|
+
nenv (~> 0.1)
|
42
|
+
shellany (~> 0.0)
|
43
|
+
pry (0.11.0)
|
44
|
+
coderay (~> 1.1.0)
|
45
|
+
method_source (~> 0.8.1)
|
46
|
+
rake (12.1.0)
|
47
|
+
rb-fsevent (0.10.2)
|
48
|
+
rb-inotify (0.9.10)
|
49
|
+
ffi (>= 0.5.0, < 2)
|
50
|
+
ruby_dep (1.5.0)
|
51
|
+
shellany (0.0.1)
|
52
|
+
thor (0.20.0)
|
53
|
+
|
54
|
+
PLATFORMS
|
55
|
+
ruby
|
56
|
+
|
57
|
+
DEPENDENCIES
|
58
|
+
bunny
|
59
|
+
guard
|
60
|
+
guard-minitest
|
61
|
+
highline
|
62
|
+
mocha
|
63
|
+
pry
|
64
|
+
rake
|
65
|
+
sevak!
|
66
|
+
|
67
|
+
BUNDLED WITH
|
68
|
+
1.15.4
|
data/Guardfile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
guard :minitest do
|
19
|
+
# with Minitest::Unit
|
20
|
+
watch(%r{^test/(.*)\/?test_(.*)\.rb$})
|
21
|
+
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
22
|
+
watch(%r{^test/test_helper\.rb$}) { 'test' }
|
23
|
+
|
24
|
+
# with Minitest::Spec
|
25
|
+
# watch(%r{^spec/(.*)_spec\.rb$})
|
26
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
27
|
+
# watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
|
28
|
+
|
29
|
+
# Rails 4
|
30
|
+
# watch(%r{^app/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
|
31
|
+
# watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
|
32
|
+
# watch(%r{^app/controllers/(.+)_controller\.rb$}) { |m| "test/integration/#{m[1]}_test.rb" }
|
33
|
+
# watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
|
34
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "test/lib/#{m[1]}_test.rb" }
|
35
|
+
# watch(%r{^test/.+_test\.rb$})
|
36
|
+
# watch(%r{^test/test_helper\.rb$}) { 'test' }
|
37
|
+
|
38
|
+
# Rails < 4
|
39
|
+
# watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
|
40
|
+
# watch(%r{^app/helpers/(.*)\.rb$}) { |m| "test/helpers/#{m[1]}_test.rb" }
|
41
|
+
# watch(%r{^app/models/(.*)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" }
|
42
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Copyright (c) 2016 Backwater Technologies Pvt Ltd
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
Sevak gem provides makes it easy to send and receive messages from rabbitmq queues. It is buit on top of the bunny gem.
|
2
|
+
|
3
|
+
|
4
|
+
Usage:
|
5
|
+
|
6
|
+
Install
|
7
|
+
|
8
|
+
gem install sevak
|
9
|
+
|
10
|
+
In your code to publish some message to a queue 'sms'.
|
11
|
+
|
12
|
+
|
13
|
+
Sevak::Publisher.publish('sms', message = { name: 'Deepak', msisdn: '9078657543' })
|
14
|
+
|
15
|
+
If the queue is not present already it will be created automatically.
|
16
|
+
|
17
|
+
|
18
|
+
To receive message from this queue and process the message a create a consumer.
|
19
|
+
|
20
|
+
|
21
|
+
class SmsConsumer < Sevak::Consumer
|
22
|
+
|
23
|
+
queue_name 'sms'
|
24
|
+
|
25
|
+
def run(message)
|
26
|
+
status = process(message)
|
27
|
+
status
|
28
|
+
end
|
29
|
+
|
30
|
+
..
|
31
|
+
end
|
32
|
+
|
33
|
+
The return status can have three values :ok, :error, :retry.
|
34
|
+
|
35
|
+
Publishing to the queue
|
36
|
+
|
37
|
+
Publisher.publish('in.chillr.email', { name: 'Deepak Kumar', message: 'welcome', email: 'deepak@chillr.in' })
|
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'sevak'
|
3
|
+
require 'highline'
|
4
|
+
|
5
|
+
# run tests by running command `rake test`
|
6
|
+
require 'rake/testtask'
|
7
|
+
|
8
|
+
Rake::TestTask.new do |t|
|
9
|
+
t.libs << 'test'
|
10
|
+
t.verbose = true
|
11
|
+
t.test_files = FileList['test/**/*_spec.rb']
|
12
|
+
t.warning = false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Load all rake tasks in the tasks folder
|
16
|
+
|
17
|
+
tasks = FileList["tasks/*.rake"]
|
18
|
+
|
19
|
+
tasks.each { |task| load(task) }
|
20
|
+
|
21
|
+
namespace :consumer do
|
22
|
+
|
23
|
+
desc 'Interactively create a new consumer'
|
24
|
+
task :new do
|
25
|
+
|
26
|
+
cli = HighLine.new
|
27
|
+
|
28
|
+
consumer_name = cli.ask('Input consumer name(eg. push_alert) :') { |q| q.validate = /\A[a-z]+[a-z_]+[a-z]\z/}
|
29
|
+
queue_name = cli.ask('Input queue name(eg. in.chillr.push.default)') { |q| q.validate = /\A[a-z]+[a-z.]+[a-z]\z/}
|
30
|
+
|
31
|
+
to_class_name = Proc.new do |name|
|
32
|
+
name.split('_').map(&:capitalize).join
|
33
|
+
end
|
34
|
+
|
35
|
+
text1 = <<-CODE
|
36
|
+
|
37
|
+
module ChillrSevak
|
38
|
+
|
39
|
+
class #{to_class_name.call(consumer_name)}Consumer < Consumer
|
40
|
+
|
41
|
+
queue_name "#{queue_name}"
|
42
|
+
|
43
|
+
def run(payload)
|
44
|
+
puts "Consumer running"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
CODE
|
51
|
+
|
52
|
+
if File.exists?("lib/sevak/consumers/#{consumer_name}_consumer.rb")
|
53
|
+
puts "Already exists file: lib/sevak/consumers/#{consumer_name}_consumer.rb"
|
54
|
+
ans = cli.ask('Do you want to overwrite it ? (y/n)') { |q| q.validate = /Y|N|y|n/}
|
55
|
+
exit(-1) if ans.downcase == 'n'
|
56
|
+
end
|
57
|
+
|
58
|
+
file = File.open("lib/sevak/consumers/#{consumer_name}_consumer.rb", 'w+')
|
59
|
+
file.write(text1)
|
60
|
+
file.close
|
61
|
+
|
62
|
+
text2 = <<-CODE
|
63
|
+
namespace :sevak do
|
64
|
+
|
65
|
+
desc "Run the #{consumer_name} worker"
|
66
|
+
task :#{consumer_name} do
|
67
|
+
consumer = ChillrSevak::#{to_class_name.call(consumer_name)}Consumer.new
|
68
|
+
consumer.start
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
CODE
|
73
|
+
|
74
|
+
if File.exists?("tasks/#{consumer_name}.rake")
|
75
|
+
puts "Already exists file: tasks/#{consumer_name}.rake"
|
76
|
+
ans = cli.ask('Do you want to overwrite it ? (y/n)') { |q| q.validate = /Y|N|y|n/}
|
77
|
+
exit(-1) if ans.downcase == 'n'
|
78
|
+
end
|
79
|
+
|
80
|
+
file = File.open("tasks/#{consumer_name}.rake", 'w+')
|
81
|
+
file.write(text2)
|
82
|
+
file.close
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'sevak'
|
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
|
data/bin/setup
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sevak/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'sevak'
|
8
|
+
spec.version = Sevak::VERSION
|
9
|
+
spec.authors = ['Deepak Kumar']
|
10
|
+
spec.email = ['deepakkumarnd@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Consumers for chillr api}
|
13
|
+
spec.description = %q{Consumers for chillr api}
|
14
|
+
spec.homepage = ''
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
# spec.add_development_dependency 'bundler', '~> 1.9'
|
23
|
+
# spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
end
|
data/lib/sevak.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
Bundler.require(:default)
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'json'
|
5
|
+
require 'logger'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'sevak/version'
|
8
|
+
|
9
|
+
module Sevak
|
10
|
+
|
11
|
+
# initialize configuration from the config/*.yml file
|
12
|
+
class Config
|
13
|
+
|
14
|
+
# allowed configurations
|
15
|
+
CONFIGURATION = %w(host port user password prefetch_count)
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
load_configuration_from_yml
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(name, *args)
|
22
|
+
setter = false
|
23
|
+
|
24
|
+
name = name.to_s
|
25
|
+
|
26
|
+
if name =~ /=$/
|
27
|
+
name = name.to_s.chop
|
28
|
+
setter = true
|
29
|
+
end
|
30
|
+
|
31
|
+
super(name, args) unless CONFIGURATION.include?(name)
|
32
|
+
|
33
|
+
if setter
|
34
|
+
set(name, args.first)
|
35
|
+
else
|
36
|
+
get(name)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def load_configuration_from_yml
|
43
|
+
@config = YAML.load(File.read('config/default.yml'))
|
44
|
+
end
|
45
|
+
|
46
|
+
def set(key, val)
|
47
|
+
@config[key] = val
|
48
|
+
end
|
49
|
+
|
50
|
+
def get(key)
|
51
|
+
@config[key]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.config
|
56
|
+
@config ||= Config.new
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.configure
|
60
|
+
yield(config) if block_given?
|
61
|
+
config
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.establish_connection
|
65
|
+
return @conn if @conn
|
66
|
+
|
67
|
+
@conn ||= Bunny.new(
|
68
|
+
host: config.host,
|
69
|
+
port: config.port,
|
70
|
+
username: config.user,
|
71
|
+
password: config.password)
|
72
|
+
|
73
|
+
@conn.start
|
74
|
+
@conn
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.get_logger
|
78
|
+
if !Dir.exist? 'log'
|
79
|
+
FileUtils.mkdir('log')
|
80
|
+
end
|
81
|
+
|
82
|
+
logfile = if !testing?
|
83
|
+
File.open('log/sevak.log', 'a')
|
84
|
+
else
|
85
|
+
File.open('log/sevak_test.log', 'a')
|
86
|
+
end
|
87
|
+
|
88
|
+
# TODO make configurable
|
89
|
+
logfile.sync = true
|
90
|
+
@logger = Logger.new(logfile, 'weekly')
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.log(data)
|
94
|
+
@logger ||= get_logger
|
95
|
+
@logger.info(data.inspect)
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.testing?
|
99
|
+
defined?(SEVAK_ENV) && (SEVAK_ENV == 'test')
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.root
|
103
|
+
File.expand_path(File.dirname(File.dirname(__FILE__)))
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
require 'sevak/core'
|
109
|
+
require 'sevak/consumer'
|
110
|
+
require 'sevak/publisher'
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Sevak
|
2
|
+
|
3
|
+
# Base class for all queue consumers, all consumers should inherit from the base Sevak::Consumer and must implement a
|
4
|
+
# run method. The run method should implement the business logic.
|
5
|
+
|
6
|
+
class ConsumerBase
|
7
|
+
|
8
|
+
include Core
|
9
|
+
|
10
|
+
DEFAULT_PREFETCH_COUNT = 10
|
11
|
+
|
12
|
+
# class methods
|
13
|
+
def self.queue_name(name='default')
|
14
|
+
@queue_name ||= name
|
15
|
+
end
|
16
|
+
# end of class methods
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@queue_name = self.class.queue_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def queue_name
|
23
|
+
@queue_name
|
24
|
+
end
|
25
|
+
|
26
|
+
def queue
|
27
|
+
@queue ||= channel.queue(queue_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def channel
|
31
|
+
@channel ||= connection.create_channel
|
32
|
+
end
|
33
|
+
|
34
|
+
def message_count
|
35
|
+
queue.message_count
|
36
|
+
end
|
37
|
+
|
38
|
+
def start
|
39
|
+
channel.prefetch(config.prefetch_count || DEFAULT_PREFETCH_COUNT)
|
40
|
+
|
41
|
+
queue.subscribe(manual_ack: true, exclusive: false) do |delivery_info, metadata, payload|
|
42
|
+
body = JSON.parse(payload)
|
43
|
+
|
44
|
+
# p delivery_info
|
45
|
+
# p metadata
|
46
|
+
|
47
|
+
begin
|
48
|
+
status = run(body)
|
49
|
+
rescue => ex
|
50
|
+
Sevak.log(exception_details(ex, payload))
|
51
|
+
status = :error
|
52
|
+
end
|
53
|
+
|
54
|
+
if status == :ok
|
55
|
+
channel.ack(delivery_info.delivery_tag)
|
56
|
+
elsif status == :retry
|
57
|
+
channel.reject(delivery_info.delivery_tag, true)
|
58
|
+
else # :error, nil etc
|
59
|
+
channel.reject(delivery_info.delivery_tag, false)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
wait_for_threads
|
64
|
+
end
|
65
|
+
|
66
|
+
def wait_for_threads
|
67
|
+
sleep
|
68
|
+
end
|
69
|
+
|
70
|
+
def exception_details(e, payload = nil)
|
71
|
+
h = {
|
72
|
+
source: "#{self.class}",
|
73
|
+
type: "#{e.class}",
|
74
|
+
message: e.message,
|
75
|
+
payload: payload.inspect,
|
76
|
+
backtrace: (e.backtrace || []).take(3).join("\n")
|
77
|
+
}
|
78
|
+
|
79
|
+
msg = h.map { |k,v| "#{k.to_s.capitalize}: #{v.to_s}"}.join(' | ')
|
80
|
+
|
81
|
+
"Sevak Exception: #{msg}"
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
class Consumer < ConsumerBase
|
87
|
+
|
88
|
+
# Set the queue name for the consumer
|
89
|
+
queue_name 'sevak.default'
|
90
|
+
|
91
|
+
def run(payload)
|
92
|
+
# implement business logic in the corresponding consumer, the run method should respond with
|
93
|
+
# status :ok, :error, :retry after the processing is over
|
94
|
+
Sevak.log("Implement run method. Payload: #{payload.inspect} #{}")
|
95
|
+
:ok
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/sevak/core.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Sevak
|
4
|
+
class Publisher
|
5
|
+
include Core
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def self.publish(queue_name, message)
|
9
|
+
instance.channel.queue(queue_name).publish(message.to_json)
|
10
|
+
end
|
11
|
+
|
12
|
+
def channel
|
13
|
+
@channel ||= connection.create_channel
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/tasks/.keep
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sevak
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Deepak Kumar
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Consumers for chillr api
|
14
|
+
email:
|
15
|
+
- deepakkumarnd@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- ".ruby-version"
|
22
|
+
- ".travis.yml"
|
23
|
+
- Gemfile
|
24
|
+
- Gemfile.lock
|
25
|
+
- Guardfile
|
26
|
+
- LICENSE.txt
|
27
|
+
- README.md
|
28
|
+
- Rakefile
|
29
|
+
- bin/console
|
30
|
+
- bin/setup
|
31
|
+
- chillr_sevak.gemspec
|
32
|
+
- config/default.yml.example
|
33
|
+
- lib/sevak.rb
|
34
|
+
- lib/sevak/consumer.rb
|
35
|
+
- lib/sevak/core.rb
|
36
|
+
- lib/sevak/publisher.rb
|
37
|
+
- lib/sevak/version.rb
|
38
|
+
- tasks/.keep
|
39
|
+
homepage: ''
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.6.8
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Consumers for chillr api
|
63
|
+
test_files: []
|
64
|
+
has_rdoc:
|