rubevent 0.1.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 +7 -0
- data/bin/rubevent +35 -0
- data/lib/rubevent.rb +1 -0
- data/lib/rubevent/event_loop.rb +87 -0
- data/lib/rubevent/metrics.rb +54 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2a47d31d4301a5295715d454905bb05eb863bf9b
|
4
|
+
data.tar.gz: f5c561b7bb10230cd6eff6f7c7ee80bfcdb1a8c8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dc681d9edc5912c953220d72767add68319f60938505c8694862293424548a964231bdcb9352587e60eda10ecde5dacea9ae9671e1c6c05ed64e576a4ce2cc40
|
7
|
+
data.tar.gz: b29349cec768f0a61324aa8f8020324f242811e2b0df888c789b2aebe5e0adeee9256be93a6ed7588f0be06a8c148427251241fdd2f96d8e0abe645602f61571
|
data/bin/rubevent
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# Get the current file location parent directory
|
4
|
+
require 'pathname'
|
5
|
+
basepath = Pathname(__FILE__).realpath.dirname.dirname.to_path
|
6
|
+
rubevent_path = basepath + "/lib"
|
7
|
+
|
8
|
+
require 'slop'
|
9
|
+
opts = Slop.parse do |o|
|
10
|
+
o.integer '-q', '--max-queue-size', 'maximum event queue size'
|
11
|
+
o.integer '-l', '--max-listeners', 'maximum number of event listeners'
|
12
|
+
o.on '-h', '--help', 'help' do; end
|
13
|
+
end
|
14
|
+
|
15
|
+
if opts[:help]
|
16
|
+
puts opts
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add rubevent to LOAD_PATH and require it
|
21
|
+
$LOAD_PATH << rubevent_path
|
22
|
+
require 'rubevent'
|
23
|
+
|
24
|
+
event_loop = Rubevent::EventLoop.new(opts.to_hash).start
|
25
|
+
event_loop.listen("event1") { |details|
|
26
|
+
puts details
|
27
|
+
}
|
28
|
+
event_loop.publish "event1", { :cool => true, :scale => 10 }
|
29
|
+
|
30
|
+
sleep 0.1
|
31
|
+
if event_loop.metrics.events_processed != 1
|
32
|
+
puts "ERROR"
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
puts "SUCCESS"
|
data/lib/rubevent.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rubevent/event_loop'
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'rubevent/metrics'
|
2
|
+
|
3
|
+
module Rubevent
|
4
|
+
|
5
|
+
class EventLoopError < StandardError; end
|
6
|
+
|
7
|
+
class EventLoop
|
8
|
+
attr_accessor :config
|
9
|
+
attr_reader :metrics
|
10
|
+
|
11
|
+
def initialize(opts = {})
|
12
|
+
@active = false
|
13
|
+
@events = []
|
14
|
+
@listeners = {}
|
15
|
+
@metrics = Metrics.new
|
16
|
+
|
17
|
+
configure opts
|
18
|
+
|
19
|
+
@loop = Thread.new do
|
20
|
+
loop do
|
21
|
+
if @events.empty? || @halted
|
22
|
+
Thread.stop
|
23
|
+
else
|
24
|
+
run
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def publish(event, details = {})
|
31
|
+
check_max_queue_size
|
32
|
+
@events.push [event, details] # array simulates pair
|
33
|
+
@metrics.received event
|
34
|
+
start unless @halted
|
35
|
+
end
|
36
|
+
|
37
|
+
def listen event_type
|
38
|
+
check_max_listeners
|
39
|
+
listener = Proc.new # wrap the passed block in a proc
|
40
|
+
listeners_for(event_type).push listener
|
41
|
+
@metrics.registered event_type
|
42
|
+
end
|
43
|
+
|
44
|
+
def start
|
45
|
+
@halted = false
|
46
|
+
@loop.wakeup
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def stop
|
51
|
+
@halted = true
|
52
|
+
end
|
53
|
+
|
54
|
+
def run
|
55
|
+
return if @events.empty? || @halted
|
56
|
+
event_type, details = @events.shift
|
57
|
+
@metrics.mark_processed event_type
|
58
|
+
listeners_for(event_type).each { |listener| listener.call details }
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def listeners_for event_type
|
63
|
+
# ensure that the listeners for an event type is an array data structure
|
64
|
+
@listeners[event_type] = [] unless @listeners[event_type].is_a? Array
|
65
|
+
@listeners[event_type]
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_max_queue_size
|
69
|
+
max_queue_size = @config[:max_queue_size]
|
70
|
+
error = max_queue_size && @events.size >= max_queue_size
|
71
|
+
raise EventLoopError if error
|
72
|
+
end
|
73
|
+
|
74
|
+
def check_max_listeners
|
75
|
+
max_listeners = @config[:max_listeners]
|
76
|
+
error = max_listeners && @listeners.values.flatten.size >= max_listeners
|
77
|
+
raise EventLoopError if error
|
78
|
+
end
|
79
|
+
|
80
|
+
def configure opts
|
81
|
+
@config = {
|
82
|
+
:max_queue_size => opts["max-queue-size".intern],
|
83
|
+
:max_listeners => opts["max-listeners".intern]
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Rubevent
|
2
|
+
class Metrics
|
3
|
+
def initialize
|
4
|
+
@events_processed = {}
|
5
|
+
@events_received = {}
|
6
|
+
@listeners_registered = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def loop_size(event_type = nil)
|
10
|
+
events_received(event_type) - events_processed(event_type)
|
11
|
+
end
|
12
|
+
|
13
|
+
def events_received(event_type = nil)
|
14
|
+
calc_hash(@events_received, event_type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def events_processed(event_type = nil)
|
18
|
+
calc_hash @events_processed, event_type
|
19
|
+
end
|
20
|
+
|
21
|
+
def num_listeners(event_type = nil)
|
22
|
+
calc_hash @listeners_registered, event_type
|
23
|
+
end
|
24
|
+
|
25
|
+
def mark_processed event_type
|
26
|
+
update_hash @events_processed, event_type
|
27
|
+
end
|
28
|
+
|
29
|
+
def received event_type
|
30
|
+
update_hash @events_received, event_type
|
31
|
+
end
|
32
|
+
|
33
|
+
def registered event_type
|
34
|
+
update_hash @listeners_registered, event_type
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def update_hash(hash, key)
|
39
|
+
if hash[key]
|
40
|
+
hash[key] += 1
|
41
|
+
else
|
42
|
+
hash[key] = 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def calc_hash(hash, key)
|
47
|
+
if key
|
48
|
+
hash[key] || 0
|
49
|
+
else
|
50
|
+
hash.values.reduce 0, :+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubevent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nikhil Narula
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: slop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.0.0
|
33
|
+
description: Minimal event loop written in Ruby
|
34
|
+
email: yahoo.is.amazing@gmail.com
|
35
|
+
executables:
|
36
|
+
- rubevent
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- bin/rubevent
|
41
|
+
- lib/rubevent.rb
|
42
|
+
- lib/rubevent/event_loop.rb
|
43
|
+
- lib/rubevent/metrics.rb
|
44
|
+
homepage: https://github.com/nn2242/rubevent
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.4.5
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: RubEvent event loop
|
68
|
+
test_files: []
|