pubsub 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ require 'autotest/growl'
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile CHANGED
@@ -7,4 +7,8 @@ group :development do
7
7
  gem "bundler", "~> 1.0.0"
8
8
  gem "jeweler", "~> 1.6.4"
9
9
  gem "rcov", ">= 0"
10
+
11
+ gem "rspec"
12
+ gem "ZenTest"
13
+ gem "autotest-growl"
10
14
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -1,61 +1,2 @@
1
1
  require "ruby_events"
2
- require File.join(File.dirname(__FILE__), "pubsub/pubsub.rb")
3
-
4
- module DigitalPro
5
- module Events
6
- module PubSub
7
- def subscribe(channel, procs = nil, &block)
8
- logger.info "Subscribe #{self.class.name} to #{channel}"
9
-
10
- PubSub.events.listen channel, procs, &block
11
-
12
- procs_collected = []
13
- if procs.respond_to?(:each) && procs.respond_to?(:to_a)
14
- procs_collected += procs.to_a
15
- elsif procs
16
- procs_collected << procs
17
- end
18
- procs_collected << block if block
19
-
20
- channel_handlers[channel] ||= []
21
- channel_handlers[channel] += procs_collected
22
- end
23
-
24
- def unsubscribe(channel=nil, proc = nil)
25
- # unsubscribe from all object channels
26
- unless channel
27
- channel_handlers.each_key{ |channel_name| unsubscribe channel_name}
28
- return
29
- end
30
-
31
- if proc
32
- logger.info "Unsubscribe #{self.class.name} to #{channel}"
33
- PubSub.events.remove channel, proc
34
- channel_handlers[channel].delete_if {|stored_event| stored_event == proc} if channel_handlers.include? channel
35
- else
36
- channel_handlers[channel].each { |proc_handler| unsubscribe channel, proc_handler} if channel_handlers.include? channel
37
- end
38
- end
39
-
40
- def publish(channel, *args)
41
- logger.info "Publish #{self.class.name} to #{channel} with #{args.to_s}"
42
-
43
- channel.sub_before "/" do |sub_channel|
44
- PubSub.events.fire sub_channel, *args
45
- end
46
- PubSub.events.fire "*", *args
47
- end
48
-
49
- protected
50
-
51
- def channel_handlers
52
- @channel_handlers ||= {}
53
- end
54
-
55
- def PubSub.events
56
- @@events ||= RubyEvents::Events.new(self)
57
- end
58
-
59
- end
60
- end
61
- end
2
+ require File.join(File.dirname(__FILE__), "pubsub/pubsub.rb")
@@ -0,0 +1,12 @@
1
+ require "logger"
2
+
3
+ class Object
4
+ @@logger = nil
5
+ def logger
6
+ unless @@logger
7
+ @@logger = Logger.new(STDERR)
8
+ @@logger.level = Logger::DEBUG
9
+ end
10
+ @@logger
11
+ end
12
+ end
@@ -1,55 +1,108 @@
1
1
  require "ruby_events"
2
+ require File.join(File.dirname(__FILE__), "logger.rb")
2
3
  require File.join(File.dirname(__FILE__), "string.rb")
3
4
 
4
5
  module PubSub
5
6
  def subscribe(channel, procs = nil, &block)
6
- logger.info "Subscribe #{self.class.name} to #{channel}"
7
+ mutex.synchronize do
8
+ logger.info "Subscribe #{self.class.name} to #{channel}"
7
9
 
8
- PubSub.events.listen channel, procs, &block
10
+ PubSub.events.listen channel, procs, &block
9
11
 
10
- procs_collected = []
11
- if procs.respond_to?(:each) && procs.respond_to?(:to_a)
12
- procs_collected += procs.to_a
13
- elsif procs
14
- procs_collected << procs
15
- end
16
- procs_collected << block if block
12
+ procs_collected = []
13
+ if procs.respond_to?(:each) && procs.respond_to?(:to_a)
14
+ procs_collected += procs.to_a
15
+ elsif procs
16
+ procs_collected << procs
17
+ end
18
+ procs_collected << block if block
17
19
 
18
- channel_handlers[channel] ||= []
19
- channel_handlers[channel] += procs_collected
20
+ channel_handlers[channel] ||= []
21
+ channel_handlers[channel] += procs_collected
22
+ end
20
23
  end
21
24
 
22
25
  def unsubscribe(channel=nil, proc = nil)
23
- # unsubscribe from all object channels
24
- unless channel
25
- channel_handlers.each_key{ |channel_name| unsubscribe channel_name}
26
- return
26
+ mutex.synchronize do
27
+ unsubscribe_safe(channel, proc )
27
28
  end
29
+ end
28
30
 
29
- if proc
30
- logger.info "Unsubscribe #{self.class.name} to #{channel}"
31
- PubSub.events.remove channel, proc
32
- channel_handlers[channel].delete_if {|stored_event| stored_event == proc} if channel_handlers.include? channel
33
- else
34
- channel_handlers[channel].each { |proc_handler| unsubscribe channel, proc_handler} if channel_handlers.include? channel
31
+ def publish(channel, *args)
32
+ mutex.synchronize do
33
+ logger.info "Add to publish queue #{self.class.name} to #{channel} with #{args.to_s}"
34
+ PubSub.queue.push({:sender => self, :channel => channel, :params => args})
35
+ PubSub.thread.wakeup if PubSub.thread.status == "sleep"
35
36
  end
36
37
  end
37
38
 
38
- def publish(channel, *args)
39
- logger.info "Publish #{self.class.name} to #{channel} with #{args.to_s}"
39
+ def PubSub.run
40
+ @@stopped = false
41
+ PubSub.thread
42
+ while true
43
+ if @@stopped
44
+ PubSub.queue.clear
45
+ break
46
+ end
47
+
48
+ sleep if PubSub.queue.empty?
49
+
50
+ unless PubSub.queue.empty?
51
+ publish_info = PubSub.queue.shift
52
+ sender = publish_info[:sender]
53
+ channel = publish_info[:channel]
54
+ params = publish_info[:params]
55
+ logger.info "Publish ObjectID:#{sender.__id__} of class #{sender.class.name} to #{channel} with #{params.to_s}"
40
56
 
41
- channel.sub_before "/" do |sub_channel|
42
- PubSub.events.fire sub_channel, *args
57
+ channel.sub_before "/" do |sub_channel|
58
+ PubSub.events.fire sub_channel, *params
59
+ end
60
+ PubSub.events.fire "*", *params
61
+ end
43
62
  end
44
- PubSub.events.fire "*", *args
63
+ end
64
+
65
+ def PubSub.stop
66
+ @@stopped = true
45
67
  end
46
68
 
47
69
  protected
48
70
 
71
+ def mutex
72
+ @mutex ||= Mutex.new
73
+ end
74
+
49
75
  def channel_handlers
50
76
  @channel_handlers ||= {}
51
77
  end
52
78
 
79
+ def unsubscribe_safe(channel=nil, proc = nil)
80
+ # unsubscribe from all object channels
81
+ unless channel
82
+ channel_handlers.each_key{ |channel_name| unsubscribe_safe channel_name}
83
+ return
84
+ end
85
+
86
+ unless proc
87
+ logger.info "Unsubscribe #{self.class.name} from #{channel}"
88
+ channel_handlers[channel].each { |proc_handler| PubSub.events.remove channel, proc_handler }if channel_handlers.include? channel
89
+ channel_handlers[channel].clear
90
+ return
91
+ end
92
+
93
+ logger.info "Unsubscribe #{self.class.name} from #{channel} listener #{proc}"
94
+ PubSub.events.remove channel, proc
95
+ channel_handlers[channel].delete_if {|stored_event| stored_event == proc} if channel_handlers.include? channel
96
+ end
97
+
98
+ def PubSub.thread
99
+ @@thread ||= Thread.current
100
+ end
101
+
102
+ def PubSub.queue
103
+ @@queue ||= []
104
+ end
105
+
53
106
  def PubSub.events
54
107
  @@events ||= RubyEvents::Events.new(self)
55
108
  end
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe "Object with PubSub pattern" do
4
+ before(:each) do
5
+ PubSub.events.events_collection.clear
6
+ @publisher = Publisher.new
7
+ @subscriber = Subscriber.new
8
+ end
9
+
10
+ it "should subscribe on channel" do
11
+ @subscriber.subscribe "channel", @subscriber.method(:listener)
12
+ PubSub.events.events_collection.size.should == 1
13
+ PubSub.events.events_collection.should have_key "channel"
14
+ end
15
+
16
+ it "should unsubscribe specific listeners from channel" do
17
+ @subscriber.subscribe "channel", @subscriber.method(:listener)
18
+ @subscriber.unsubscribe "channel", @subscriber.method(:listener)
19
+ PubSub.events.events_collection["channel"].should be_empty
20
+ end
21
+
22
+ it "should unsubscribe all listeners from channel" do
23
+ @subscriber.subscribe "channel", @subscriber.method(:listener)
24
+ @subscriber.subscribe "channel", @subscriber.method(:listener1)
25
+ @subscriber.unsubscribe "channel"
26
+ PubSub.events.events_collection["channel"].should be_empty
27
+ end
28
+
29
+ it "should unsubscribe from all channels" do
30
+ @subscriber.subscribe "channel", @subscriber.method(:listener)
31
+ @subscriber.subscribe "channel1", @subscriber.method(:listener1)
32
+ @subscriber.unsubscribe
33
+ PubSub.events.events_collection["channel"].should be_empty
34
+ PubSub.events.events_collection["channel1"].should be_empty
35
+ end
36
+
37
+ it "should publish message to channel" do
38
+ @subscriber.should_receive(:listener).with("Hello world")
39
+ @subscriber.subscribe "channel", @subscriber.method(:listener)
40
+ @subscriber.subscribe "channel", @subscriber.method(:listener_with_stop)
41
+ @publisher.publish("channel", "Hello world")
42
+ PubSub.run
43
+ end
44
+
45
+ it "should publish message to channel and subchannel" do
46
+ @subscriber.should_receive(:listener).with("Hello world")
47
+ @subscriber.subscribe "test/channel", @subscriber.method(:listener)
48
+
49
+ @subscriber.should_receive(:listener1).with("Hello world")
50
+ @subscriber.subscribe "test", @subscriber.method(:listener1)
51
+
52
+ @subscriber.subscribe "test/channel", @subscriber.method(:listener_with_stop)
53
+ @publisher.publish("test/channel", "Hello world")
54
+ PubSub.run
55
+ end
56
+
57
+ it "should publish message to global channel" do
58
+ @subscriber.should_receive(:listener).with("Hello world")
59
+ @subscriber.subscribe "*", @subscriber.method(:listener)
60
+ @subscriber.subscribe "*", @subscriber.method(:listener_with_stop)
61
+ @publisher.publish("channel", "Hello world")
62
+ PubSub.run
63
+ end
64
+ end
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ require 'pubsub'
14
+
15
+ logger.level = Logger::WARN
16
+
17
+ module PubSub
18
+ PubSub.events.class.class_eval do
19
+ def events_collection
20
+ @events
21
+ end
22
+ end
23
+ end
24
+
25
+ class Publisher
26
+ include PubSub
27
+ end
28
+
29
+ class Subscriber
30
+ include PubSub
31
+
32
+ def listener(message = nil)
33
+ logger.info "listener_with_stop"
34
+ end
35
+
36
+ def listener1(message = nil)
37
+ end
38
+
39
+ def listener_with_stop(message = nil)
40
+ PubSub.stop
41
+ end
42
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-15 00:00:00.000000000 +04:00
12
+ date: 2011-07-17 00:00:00.000000000 +04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ruby_events
17
- requirement: &11460780 !ruby/object:Gem::Requirement
17
+ requirement: &18948040 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *11460780
25
+ version_requirements: *18948040
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: shoulda
28
- requirement: &11458140 !ruby/object:Gem::Requirement
28
+ requirement: &18946840 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *11458140
36
+ version_requirements: *18946840
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: bundler
39
- requirement: &11419840 !ruby/object:Gem::Requirement
39
+ requirement: &18946080 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.0.0
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *11419840
47
+ version_requirements: *18946080
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: jeweler
50
- requirement: &11418620 !ruby/object:Gem::Requirement
50
+ requirement: &18945200 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.6.4
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *11418620
58
+ version_requirements: *18945200
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: rcov
61
- requirement: &11417000 !ruby/object:Gem::Requirement
61
+ requirement: &18944220 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,43 @@ dependencies:
66
66
  version: '0'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *11417000
69
+ version_requirements: *18944220
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: &18943460 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *18943460
81
+ - !ruby/object:Gem::Dependency
82
+ name: ZenTest
83
+ requirement: &18928680 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *18928680
92
+ - !ruby/object:Gem::Dependency
93
+ name: autotest-growl
94
+ requirement: &18927540 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *18927540
70
103
  - !ruby/object:Gem::Dependency
71
104
  name: ruby_events
72
- requirement: &11414840 !ruby/object:Gem::Requirement
105
+ requirement: &18921320 !ruby/object:Gem::Requirement
73
106
  none: false
74
107
  requirements:
75
108
  - - ! '>='
@@ -77,7 +110,7 @@ dependencies:
77
110
  version: '0'
78
111
  type: :runtime
79
112
  prerelease: false
80
- version_requirements: *11414840
113
+ version_requirements: *18921320
81
114
  description: PubSub pattern
82
115
  email: maxkazargm@gmail.com
83
116
  executables: []
@@ -86,17 +119,21 @@ extra_rdoc_files:
86
119
  - LICENSE.txt
87
120
  - README.rdoc
88
121
  files:
122
+ - .autotest
89
123
  - .document
124
+ - .rspec
90
125
  - Gemfile
91
126
  - LICENSE.txt
92
127
  - README.rdoc
93
128
  - Rakefile
94
129
  - VERSION
130
+ - autotest/discover.rb
95
131
  - lib/pubsub.rb
132
+ - lib/pubsub/logger.rb
96
133
  - lib/pubsub/pubsub.rb
97
134
  - lib/pubsub/string.rb
98
- - test/helper.rb
99
- - test/test_pubsub.rb
135
+ - spec/pubsup_spec.rb
136
+ - spec/spec_helper.rb
100
137
  has_rdoc: true
101
138
  homepage: http://github.com/maxkazar/pubsub
102
139
  licenses:
@@ -113,7 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
150
  version: '0'
114
151
  segments:
115
152
  - 0
116
- hash: 3917047595112901718
153
+ hash: -2541202216032154175
117
154
  required_rubygems_version: !ruby/object:Gem::Requirement
118
155
  none: false
119
156
  requirements:
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
-
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
15
- require 'pubsub'
16
-
17
- class Test::Unit::TestCase
18
- end
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestPubsub < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end