eventhub-processor2 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.travis.yml +36 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +76 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docker/Dockerfile +6 -0
- data/docker/README.md +14 -0
- data/docker/definitions.json +87 -0
- data/docker/rabbitmq.config +16 -0
- data/eventhub-processor2.gemspec +34 -0
- data/example/README.md +19 -0
- data/example/config/example.json +19 -0
- data/example/crasher.rb +57 -0
- data/example/example.rb +25 -0
- data/example/publisher.rb +95 -0
- data/lib/eventhub/actor_heartbeat.rb +121 -0
- data/lib/eventhub/actor_listener.rb +161 -0
- data/lib/eventhub/actor_watchdog.rb +41 -0
- data/lib/eventhub/configuration.rb +114 -0
- data/lib/eventhub/constant.rb +35 -0
- data/lib/eventhub/consumer.rb +9 -0
- data/lib/eventhub/hash_extensions.rb +49 -0
- data/lib/eventhub/helper.rb +55 -0
- data/lib/eventhub/logger.rb +14 -0
- data/lib/eventhub/message.rb +158 -0
- data/lib/eventhub/processor2.rb +121 -0
- data/lib/eventhub/statistics.rb +53 -0
- data/lib/eventhub/version.rb +3 -0
- data/lib/eventhub.rb +25 -0
- metadata +190 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
# EventHub module
|
2
|
+
module EventHub
|
3
|
+
# Message class
|
4
|
+
class Message
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
VERSION = '1.0.0'.freeze
|
8
|
+
|
9
|
+
# Headers that are required (value can be nil) in order to pass valid?
|
10
|
+
REQUIRED_HEADERS = [
|
11
|
+
'message_id',
|
12
|
+
'version',
|
13
|
+
'created_at',
|
14
|
+
'origin.module_id',
|
15
|
+
'origin.type',
|
16
|
+
'origin.site_id',
|
17
|
+
'process.name',
|
18
|
+
'process.step_position',
|
19
|
+
'process.execution_id',
|
20
|
+
'status.retried_count',
|
21
|
+
'status.code',
|
22
|
+
'status.message'
|
23
|
+
].freeze
|
24
|
+
|
25
|
+
attr_accessor :header, :body, :raw, :vhost, :routing_key
|
26
|
+
|
27
|
+
# Build accessors for all required headers
|
28
|
+
REQUIRED_HEADERS.each do |header|
|
29
|
+
name = header.tr('.', '_')
|
30
|
+
|
31
|
+
define_method(name) do
|
32
|
+
self.header.get(header)
|
33
|
+
end
|
34
|
+
|
35
|
+
define_method("#{name}=") do |value|
|
36
|
+
self.header.set(header, value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.from_json(raw)
|
41
|
+
data = JSON.parse(raw)
|
42
|
+
Message.new(data.get('header'), data.get('body'), raw)
|
43
|
+
rescue => e
|
44
|
+
Message.new(
|
45
|
+
{
|
46
|
+
'status' =>
|
47
|
+
{
|
48
|
+
'code' => STATUS_INVALID,
|
49
|
+
'message' => "JSON parse error: #{e}"
|
50
|
+
}
|
51
|
+
},
|
52
|
+
{
|
53
|
+
'original_message_base64_encoded' => Base64.encode64(raw)
|
54
|
+
},
|
55
|
+
raw
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(header = nil, body = nil, raw = nil)
|
60
|
+
@header = header || {}
|
61
|
+
@body = body || {}
|
62
|
+
@raw = raw
|
63
|
+
|
64
|
+
# set message defaults, that we have required headers
|
65
|
+
@header.set('message_id', UUIDTools::UUID.timestamp_create.to_s, false)
|
66
|
+
@header.set('version', VERSION, false)
|
67
|
+
@header.set('created_at', now_stamp, false)
|
68
|
+
|
69
|
+
@header.set('origin.module_id', 'undefined', false)
|
70
|
+
@header.set('origin.type', 'undefined', false)
|
71
|
+
@header.set('origin.site_id', 'undefined', false)
|
72
|
+
|
73
|
+
@header.set('process.name', 'undefined', false)
|
74
|
+
@header.set('process.execution_id',
|
75
|
+
UUIDTools::UUID.timestamp_create.to_s, false)
|
76
|
+
@header.set('process.step_position', 0, false)
|
77
|
+
|
78
|
+
@header.set('status.retried_count', 0, false)
|
79
|
+
@header.set('status.code', STATUS_INITIAL, false)
|
80
|
+
@header.set('status.message', '', false)
|
81
|
+
end
|
82
|
+
|
83
|
+
def valid?
|
84
|
+
# check for existence and defined value
|
85
|
+
REQUIRED_HEADERS.all? do |key|
|
86
|
+
@header.all_keys_with_path.include?(key) &&
|
87
|
+
!send(key.tr('.', '_').to_sym).nil?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def success?
|
92
|
+
status_code == STATUS_SUCCESS
|
93
|
+
end
|
94
|
+
|
95
|
+
def retry?
|
96
|
+
status_code == STATUS_RETRY
|
97
|
+
end
|
98
|
+
|
99
|
+
def initial?
|
100
|
+
status_code == STATUS_INITIAL
|
101
|
+
end
|
102
|
+
|
103
|
+
def retry_pending?
|
104
|
+
status_code == STATUS_RETRY_PENDING
|
105
|
+
end
|
106
|
+
|
107
|
+
def invalid?
|
108
|
+
status_code == STATUS_INVALID
|
109
|
+
end
|
110
|
+
|
111
|
+
def schedule?
|
112
|
+
status_code == STATUS_SCHEDULE
|
113
|
+
end
|
114
|
+
|
115
|
+
def schedule_retry?
|
116
|
+
status_code == STATUS_SCHEDULE_RETRY
|
117
|
+
end
|
118
|
+
|
119
|
+
def schedule_pending?
|
120
|
+
status_code == STATUS_SCHEDULE_PENDING
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_json
|
124
|
+
{ 'header' => header, 'body' => body }.to_json
|
125
|
+
end
|
126
|
+
|
127
|
+
def to_s
|
128
|
+
'Msg: process '\
|
129
|
+
"[#{process_name}, #{process_step_position}, #{process_execution_id}]"\
|
130
|
+
", status [#{status_code},#{status_message},#{status_retried_count}]"
|
131
|
+
end
|
132
|
+
|
133
|
+
# copies the message and set's provided status code (default: success),
|
134
|
+
# actual stamp, and a new message id
|
135
|
+
def copy(status_code = STATUS_SUCCESS)
|
136
|
+
# use Marshal dump and load to make a deep object copy
|
137
|
+
copied_header = Marshal.load(Marshal.dump(header))
|
138
|
+
copied_body = Marshal.load(Marshal.dump(body))
|
139
|
+
|
140
|
+
copied_header.set('message_id', UUIDTools::UUID.timestamp_create.to_s)
|
141
|
+
copied_header.set('created_at', now_stamp)
|
142
|
+
copied_header.set('status.code', status_code)
|
143
|
+
|
144
|
+
Message.new(copied_header, copied_body)
|
145
|
+
end
|
146
|
+
|
147
|
+
def append_to_execution_history(processor_name)
|
148
|
+
header.set('execution_history', []) unless \
|
149
|
+
header.get('execution_history')
|
150
|
+
header.get('execution_history') << \
|
151
|
+
{ 'processor' => processor_name, 'timestamp' => now_stamp }
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.translate_status_code(code)
|
155
|
+
STATUS_CODE_TRANSLATION[code]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# EventHub module
|
2
|
+
module EventHub
|
3
|
+
# Processor2 class
|
4
|
+
class Processor2
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
SIGNALS_FOR_TERMINATION = [:INT, :TERM, :QUIT]
|
8
|
+
SIGNALS_FOR_RELOAD_CONFIG = [:HUP]
|
9
|
+
ALL_SIGNALS = SIGNALS_FOR_TERMINATION + SIGNALS_FOR_RELOAD_CONFIG
|
10
|
+
|
11
|
+
attr_reader :started_at, :statistics
|
12
|
+
|
13
|
+
def initialize(args = {})
|
14
|
+
# Set processor name
|
15
|
+
EventHub::Configuration.name = args[:name] ||
|
16
|
+
get_name_from_class(self)
|
17
|
+
|
18
|
+
# Parse comand line options
|
19
|
+
EventHub::Configuration.parse_options
|
20
|
+
|
21
|
+
# Load configuration file
|
22
|
+
EventHub::Configuration.load!(args)
|
23
|
+
|
24
|
+
@command_queue = []
|
25
|
+
|
26
|
+
@started_at = Time.now
|
27
|
+
@statistics = EventHub::Statistics.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def start
|
31
|
+
EventHub.logger.info("#{Configuration.name} (#{version}): has been started")
|
32
|
+
|
33
|
+
before_start
|
34
|
+
main_event_loop
|
35
|
+
after_stop
|
36
|
+
|
37
|
+
EventHub.logger.info("#{Configuration.name} (#{version}): has been stopped")
|
38
|
+
rescue => ex
|
39
|
+
EventHub.logger.error("Unexpected error in Processor2.start: #{ex}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def stop
|
43
|
+
# used by rspec
|
44
|
+
@command_queue << :TERM
|
45
|
+
end
|
46
|
+
|
47
|
+
def version
|
48
|
+
EventHub::VERSION
|
49
|
+
end
|
50
|
+
|
51
|
+
# get message as EventHub::Message class instance
|
52
|
+
# args contain :queue_name, :content_type, :priority, :delivery_tag
|
53
|
+
def handle_message(_message, _args = {})
|
54
|
+
raise 'need to be implemented in derived class'
|
55
|
+
end
|
56
|
+
|
57
|
+
# pass message: '{ "header": ... , "body": { .. }}'
|
58
|
+
# and optionally exchange_name: 'your exchange name'
|
59
|
+
def publish(args = {})
|
60
|
+
Celluloid::Actor[:actor_listener].publish(args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def before_start
|
64
|
+
# can be implemented in derived class
|
65
|
+
end
|
66
|
+
|
67
|
+
def after_stop
|
68
|
+
# can be implemented in derived class
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def setup_signal_handler
|
74
|
+
# have a re-entrant signal handler by just using a simple array
|
75
|
+
# https://www.sitepoint.com/the-self-pipe-trick-explained/
|
76
|
+
ALL_SIGNALS.each do |signal|
|
77
|
+
Signal.trap(signal) { @command_queue << signal }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def start_supervisor
|
82
|
+
@config = Celluloid::Supervision::Configuration.define([
|
83
|
+
{type: ActorHeartbeat, as: :actor_heartbeat, args: [ self ]},
|
84
|
+
{type: ActorListener, as: :actor_listener, args: [ self ]}
|
85
|
+
])
|
86
|
+
|
87
|
+
@config.injection!(:before_restart, proc do
|
88
|
+
EventHub.logger.info('Restarting in 10 seconds...')
|
89
|
+
sleep 10
|
90
|
+
end )
|
91
|
+
|
92
|
+
@config.deploy
|
93
|
+
end
|
94
|
+
|
95
|
+
def main_event_loop
|
96
|
+
setup_signal_handler
|
97
|
+
start_supervisor
|
98
|
+
|
99
|
+
loop do
|
100
|
+
command = @command_queue.pop
|
101
|
+
case
|
102
|
+
when SIGNALS_FOR_TERMINATION.include?(command)
|
103
|
+
EventHub.logger.info("Command [#{command}] received")
|
104
|
+
break
|
105
|
+
when SIGNALS_FOR_RELOAD_CONFIG.include?(command)
|
106
|
+
EventHub::Configuration.load!
|
107
|
+
EventHub.logger.info('Configuration file reloaded')
|
108
|
+
Celluloid::Actor[:actor_listener].async.restart
|
109
|
+
else
|
110
|
+
sleep 0.5
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
Celluloid.shutdown
|
115
|
+
# make sure all actors are gone
|
116
|
+
while Celluloid.running?
|
117
|
+
sleep 0.1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class EventHub::Statistics
|
2
|
+
attr_reader :messages_successful, :messages_unsuccessful, :messages_average_size, :messages_average_process_time
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@messages_successful = 0
|
6
|
+
@messages_unsuccessful = 0
|
7
|
+
@messages_average_size = 0
|
8
|
+
@messages_average_process_time = 0
|
9
|
+
@messages_total_process_time = 0
|
10
|
+
@mutex = Mutex.new
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def measure(size, &block)
|
15
|
+
begin
|
16
|
+
start = Time.now
|
17
|
+
yield
|
18
|
+
success(Time.now - start, size)
|
19
|
+
rescue
|
20
|
+
failure
|
21
|
+
raise
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def success(process_time, size)
|
26
|
+
@mutex.lock
|
27
|
+
@messages_total_process_time += process_time
|
28
|
+
@messages_average_process_time = (messages_total_process_time + process_time) / (messages_successful + 1).to_f
|
29
|
+
@messages_average_size = (messages_total_size + size) / (messages_successful + 1).to_f
|
30
|
+
@messages_successful += 1
|
31
|
+
ensure
|
32
|
+
@mutex.unlock
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure
|
36
|
+
@mutex.lock
|
37
|
+
@messages_unsuccessful += 1
|
38
|
+
ensure
|
39
|
+
@mutex.unlock
|
40
|
+
end
|
41
|
+
|
42
|
+
def messages_total
|
43
|
+
messages_unsuccessful + messages_successful
|
44
|
+
end
|
45
|
+
|
46
|
+
def messages_total_process_time
|
47
|
+
messages_average_process_time * messages_successful
|
48
|
+
end
|
49
|
+
|
50
|
+
def messages_total_size
|
51
|
+
messages_average_size * messages_successful
|
52
|
+
end
|
53
|
+
end
|
data/lib/eventhub.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'uuidtools'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
require 'eventhub/components'
|
6
|
+
require 'logstash-logger'
|
7
|
+
require 'bunny'
|
8
|
+
require 'celluloid/current'
|
9
|
+
|
10
|
+
require_relative 'eventhub/version'
|
11
|
+
require_relative 'eventhub/constant'
|
12
|
+
require_relative 'eventhub/logger'
|
13
|
+
require_relative 'eventhub/helper'
|
14
|
+
require_relative 'eventhub/hash_extensions'
|
15
|
+
require_relative 'eventhub/configuration'
|
16
|
+
require_relative 'eventhub/message'
|
17
|
+
require_relative 'eventhub/statistics'
|
18
|
+
require_relative 'eventhub/consumer'
|
19
|
+
require_relative 'eventhub/actor_heartbeat'
|
20
|
+
require_relative 'eventhub/actor_watchdog'
|
21
|
+
require_relative 'eventhub/actor_listener'
|
22
|
+
require_relative 'eventhub/processor2'
|
23
|
+
|
24
|
+
Celluloid.logger = nil
|
25
|
+
Celluloid.exception_handler { |ex| EventHub.logger.info "Exception occured: #{ex}" }
|
metadata
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eventhub-processor2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steiner, Thomas
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: celluloid
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.17'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bunny
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: eventhub-components
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: uuidtools
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.16'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.16'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '12.2'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '12.2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.7'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.7'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.15'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.15'
|
125
|
+
description: Next generation gem to build ruby based eventhub processor
|
126
|
+
email:
|
127
|
+
- thomas.steiner@ikey.ch
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".travis.yml"
|
135
|
+
- Gemfile
|
136
|
+
- Gemfile.lock
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- bin/console
|
141
|
+
- bin/setup
|
142
|
+
- docker/Dockerfile
|
143
|
+
- docker/README.md
|
144
|
+
- docker/definitions.json
|
145
|
+
- docker/rabbitmq.config
|
146
|
+
- eventhub-processor2.gemspec
|
147
|
+
- example/README.md
|
148
|
+
- example/config/example.json
|
149
|
+
- example/crasher.rb
|
150
|
+
- example/example.rb
|
151
|
+
- example/publisher.rb
|
152
|
+
- lib/eventhub.rb
|
153
|
+
- lib/eventhub/actor_heartbeat.rb
|
154
|
+
- lib/eventhub/actor_listener.rb
|
155
|
+
- lib/eventhub/actor_watchdog.rb
|
156
|
+
- lib/eventhub/configuration.rb
|
157
|
+
- lib/eventhub/constant.rb
|
158
|
+
- lib/eventhub/consumer.rb
|
159
|
+
- lib/eventhub/hash_extensions.rb
|
160
|
+
- lib/eventhub/helper.rb
|
161
|
+
- lib/eventhub/logger.rb
|
162
|
+
- lib/eventhub/message.rb
|
163
|
+
- lib/eventhub/processor2.rb
|
164
|
+
- lib/eventhub/statistics.rb
|
165
|
+
- lib/eventhub/version.rb
|
166
|
+
homepage: https://github.com/thomis/eventhub-processor2
|
167
|
+
licenses:
|
168
|
+
- MIT
|
169
|
+
metadata: {}
|
170
|
+
post_install_message:
|
171
|
+
rdoc_options: []
|
172
|
+
require_paths:
|
173
|
+
- lib
|
174
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
requirements: []
|
185
|
+
rubyforge_project:
|
186
|
+
rubygems_version: 2.6.12
|
187
|
+
signing_key:
|
188
|
+
specification_version: 4
|
189
|
+
summary: Next generation gem to build ruby based eventhub processor
|
190
|
+
test_files: []
|