langrove 0.0.4.3 → 0.0.4.4

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.
data/bin/langrove CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- puts "mooo"
3
+ puts "warbel"
@@ -1,12 +1,13 @@
1
1
  :daemons:
2
2
  datagram:
3
3
  :periodic: 5
4
+ :protocol:
5
+ :class: SocketToFile
4
6
  :adaptor:
5
- :connection: Datagram
6
- :iface: 127.0.0.1
7
- :port: 12701
8
- :client:
9
- :class: Datagram
7
+ :connection: Datagram
8
+ :iface: 127.0.0.1
9
+ :port: 12701
10
+ :client:
11
+ :class: SocketToFile
10
12
  :handler:
11
- :collection: SocketToFile
12
- :protocol: SocketToFile
13
+ :collection: Base
@@ -21,7 +21,7 @@ DaemonKit::Initializer.run do |config|
21
21
  # TODO: move log level into per daemon config
22
22
  #
23
23
  #config.log_level = :debug
24
- config.log_level = :info
24
+ config.log_level = :debug
25
25
  #config.log_level = :warn
26
26
  #config.log_level = :error
27
27
 
@@ -0,0 +1,47 @@
1
+ #
2
+ # Define a Client by extending LanGrove::Handler::Client
3
+ # and extending the functions:
4
+ #
5
+ # 1. <YourClass>.receive( decoded_data )
6
+ #
7
+ # Data arriving from the Adaptor will arrive into
8
+ # this function having already been decoded by the
9
+ # configured Protocol for this Daemon
10
+ #
11
+ # # 2. <YourClass>.transmit
12
+ # #
13
+
14
+ require 'langrove'
15
+
16
+ module Client
17
+
18
+ class SocketToFile < LanGrove::Client::Base
19
+
20
+ def periodic
21
+
22
+ #
23
+ # OVERRIDE
24
+ #
25
+ # To perform activities on the periodic ticker.
26
+ #
27
+ @logger.debug( "#{self}.periodic" )
28
+
29
+ end
30
+
31
+ def receive( data )
32
+
33
+ @logger.debug( "#{self}.receive: #{data}" )
34
+
35
+ File.open( data[:filename], 'w' ) do |f|
36
+
37
+ f.write( data[:content] )
38
+
39
+ end
40
+
41
+ @logger.debug "Wrote data: '#{data[ :content ]}' to file: '#{ data[ :filename ]}'"
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -39,7 +39,7 @@ module Protocol
39
39
  # Becasuse your protocol
40
40
  #
41
41
 
42
- @logger.info( "#{self}.decode: #{data}" ) unless @logger.nil?
42
+ @logger.debug( "#{self}.decode: #{data}" ) unless @logger.nil?
43
43
 
44
44
  {
45
45
 
@@ -4,22 +4,58 @@ module LanGrove::Adaptor
4
4
 
5
5
  class Datagram < Base
6
6
 
7
- def listen( handler, protocol )
7
+ def listen( client, protocol, handler )
8
+
9
+ #
10
+ # <client> = {
11
+ #
12
+ # :class => <loaded class constant>
13
+ # :config => <client's branch of config>
14
+ #
15
+ # }
16
+ #
17
+ # <protocol> = { ...the same, but protocolic }
18
+ #
19
+ #
8
20
 
9
21
  @logger.info "starting listen at UDP #{@iface}:#{@port}"
10
22
 
11
23
  EventMachine::open_datagram_socket( @iface, @port,
12
24
 
13
- @client ) do |client|
25
+ client[:class] ) do | client_connected |
26
+
27
+ #
28
+ # EM::open_datagram_socket (udp) yields on connect
29
+ # to the socket.
30
+ #
31
+ # EM::start_server (tcp) yields on connect from the
32
+ # client.
33
+ #
34
+
35
+ #
36
+ # Initialize the client with a Protocol
37
+ #
38
+
39
+ client_connected.logger = @logger
40
+
41
+ client_connected.config = client[ :config ]
14
42
 
15
- @logger.info "client assign handler: #{handler}"
16
- client.handler = handler
43
+ client_connected.protocol = protocol[ :class ]\
17
44
 
18
- @logger.info "client instanciate protocol: #{protocol}"
19
- client.protocol = protocol.new( nil, @logger )
45
+ .new( protocol[ :config ], @logger )
46
+
47
+ @logger.info( "TODO: make a reference to the Client on the Handler" )
48
+
49
+ #
50
+ # Insert the Client into th Handler collection
51
+ #
52
+ handler.connect( client_connected )
20
53
 
21
- @logger.info "client assign config: #{@client_config}"
22
- client.config = @client_config.clone
54
+ #
55
+ # Client is ready and running inside the reactor
56
+ #
57
+ # EM::start_server will yield again on the next connect.
58
+ #
23
59
 
24
60
  end
25
61
  end
@@ -24,61 +24,10 @@ module LanGrove::Adaptor
24
24
  #
25
25
 
26
26
  end
27
-
28
- #
29
- # initialize the client specified in config
30
- #
31
- # daemons:
32
- # name_of_daemon:
33
- # adaptor:
34
- # connection: TcpServer
35
- # client:
36
- # class: Client <---------
37
- # handler:
38
- # collection: CollectionOfClients
39
- #
40
- #
41
-
42
- @logger.info "TODO: loading client is not tested"
43
-
44
- client = nil
45
-
46
- begin
47
-
48
- #
49
- # TODO: make this more informative on error
50
- #
51
-
52
- @client_config = @config[ :client ]
53
- client = @client_config[ :class ]
54
-
55
- rescue
56
-
57
- error = "Missing config item(s) for adaptor: #{@config.inspect}"
58
-
59
- @logger.error "EXIT: #{error}"
60
-
61
- raise LanGrove::DaemonConfigException.new(
62
-
63
- "Missing config item for daemon: #{@daemon_name}"
64
-
65
- )
66
-
67
- end
68
-
69
- @logger.info "Load definition: Client::#{client}"
70
-
71
- @client = LanGrove::ClassLoader.create( {
72
-
73
- :module => 'Client',
74
- :class => client
75
-
76
- } )
77
-
78
27
 
79
28
  end
80
29
 
81
- def listen( handler, protocol )
30
+ def listen( client, protocol, handler )
82
31
 
83
32
  raise LanGrove::DaemonConfigException.new( "NotYetExtended: undefined listen()" )
84
33
 
@@ -26,13 +26,11 @@ module LanGrove
26
26
  # their actual client..
27
27
  #
28
28
 
29
- #
30
- # The handler collection specified in config
31
- # is bound to this attribute after connect.
32
- #
33
29
  attr_accessor :handler
34
30
  attr_accessor :protocol
35
31
  attr_accessor :config
32
+ attr_accessor :logger
33
+
36
34
 
37
35
  #
38
36
  # Data arriving through the Adaptor is passed
@@ -51,8 +49,8 @@ module LanGrove
51
49
  # - It has passed through the protocol as
52
50
  # defined in config.
53
51
  #
54
- # The protocol arranged the data into
55
- # a Hash of:
52
+ # The protocol should have arranged the data
53
+ # into a Hash of:
56
54
  #
57
55
  # - key and value pairs
58
56
  #
@@ -67,42 +65,6 @@ module LanGrove
67
65
 
68
66
  def receive_data( data )
69
67
 
70
- #
71
- # Note: The protocol currently lives on the Handler
72
- #
73
- # It MIG( ...in progress... )HT move,
74
- #
75
- # To a separate instance of the protocol object
76
- # residing in each Client::ClientType instance
77
- # in the Handler::Base.client collection.
78
- #
79
- # Pending examining the logical barrier of having
80
- # the Handler route to the Cleint per a key value
81
- # extracted from the decoded data - as decoded by
82
- # the client's instance of the protocol not yet
83
- # accessable within the as yet undeterminable
84
- # instance in the Handlers collection.
85
- #
86
- # Catch22(ish)
87
- #
88
- # But that was suitable as a pettern for the
89
- # datagram server.
90
- #
91
- # Perhaps after implementing Adapter::TcpServer
92
- #
93
- # And gaining a more knowsome notion of the
94
- # intricacies of the application layer, esp
95
- # ACKing and NAKing.
96
- #
97
- # Then the possibilities of the Client::ClientType
98
- # being a decendant of <self> --
99
- #
100
- # ie. The EM::Connection as instanciated upon each
101
- # socket connect.
102
- #
103
- # -- will likely resolve.
104
- #
105
- #
106
68
  receive( @protocol.decode( data ) )
107
69
 
108
70
  end
@@ -7,11 +7,23 @@ module LanGrove::Daemon class Base
7
7
  def listen
8
8
 
9
9
  #
10
- # Handler - The CollectionOfClients, is passed
11
- # through the adaptor to be assigned
12
- # to the attaching Clients.
10
+ # <Client> and <Protocol> are passed into
11
+ # the Adaptor.listen for binding onto the
12
+ # sockets at connect.
13
13
  #
14
- @adaptor.listen( @handler, @handler.protocol )
14
+ @adaptor.listen(
15
+
16
+ #
17
+ # pass Client, Protocol and Handler to 'listener'
18
+ #
19
+
20
+ { :class => @client, :config => @my_config[ :client ] },
21
+
22
+ { :class => @protocol, :config => @my_config[ :protocol ] },
23
+
24
+ @handler
25
+
26
+ )
15
27
 
16
28
  end
17
29
 
@@ -84,10 +96,20 @@ module LanGrove::Daemon class Base
84
96
  @adaptor = nil
85
97
 
86
98
  #
87
- # A handler to direct the traffic.
99
+ # The client collection class.
88
100
  #
89
101
  @handler = nil
90
102
 
103
+ #
104
+ # The client type
105
+ #
106
+ @client = nil
107
+
108
+ #
109
+ # The protocol type
110
+ #
111
+ @protocol = nil
112
+
91
113
 
92
114
  begin
93
115
 
@@ -108,9 +130,19 @@ module LanGrove::Daemon class Base
108
130
 
109
131
  @server = @my_config[ :server ] if @my_config.has_key? :server
110
132
 
133
+ @logger.info "TODO: fall back to default Adaptor::Base"
134
+
111
135
  adaptor = @my_config[ :adaptor ][ :connection ]
112
136
 
137
+ @logger.info "TODO: fall back to default Handler::Base"
138
+
113
139
  handler = @my_config[ :handler ][ :collection ]
140
+
141
+ client = @my_config[ :client ][ :class ]
142
+
143
+ protocol = @my_config[ :protocol ][ :class ]
144
+
145
+ @logger.info "TODO: Warn instead of raise and allow nil into ClassLoader -> load default"
114
146
 
115
147
  rescue
116
148
 
@@ -126,6 +158,7 @@ module LanGrove::Daemon class Base
126
158
 
127
159
  end
128
160
 
161
+
129
162
  #
130
163
  # initialize the connection adaptor specified in config
131
164
  #
@@ -137,7 +170,7 @@ module LanGrove::Daemon class Base
137
170
  # collection: CollectionOfClients
138
171
  #
139
172
 
140
- @logger.info "Initialize instance: Adaptor::#{adaptor}.new( @my_config[ :adaptor ], logger )"
173
+ @logger.info "CREATE: Adaptor::#{adaptor}.new( @my_config[ :adaptor ], logger )"
141
174
 
142
175
  @adaptor = LanGrove::ClassLoader.create( {
143
176
 
@@ -160,7 +193,7 @@ module LanGrove::Daemon class Base
160
193
  # CollectionOfClients ---> is the handler passed into listen()
161
194
  #
162
195
 
163
- @logger.info "Initialize instance: Handler::#{handler}.new( config_hash, '#{daemon_name}', logger )"
196
+ @logger.info "CREATE: Handler::#{handler}.new( config_hash, '#{daemon_name}', logger )"
164
197
 
165
198
  @handler = LanGrove::ClassLoader.create( {
166
199
 
@@ -169,6 +202,58 @@ module LanGrove::Daemon class Base
169
202
 
170
203
  } ).new( @config, @daemon_name, @logger )
171
204
 
205
+
206
+ #
207
+ # initialize the client specified in config
208
+ #
209
+ # daemons:
210
+ # name_of_daemon:
211
+ # client:
212
+ # class: Client <---------
213
+ # adaptor:
214
+ # connection: TcpServer
215
+ # handler:
216
+ # collection: CollectionOfClients
217
+ #
218
+ #
219
+
220
+ @logger.info "DEFINE: Client::#{client}"
221
+
222
+ @client = LanGrove::ClassLoader.create( {
223
+
224
+ :module => 'Client',
225
+ :class => client
226
+
227
+ } )
228
+
229
+
230
+ #
231
+ # initialize the client specified in config
232
+ #
233
+ # daemons:
234
+ # name_of_daemon:
235
+ # protocol:
236
+ # class: Protocol <---------
237
+ # more: config
238
+ # client:
239
+ # class: Client
240
+ # adaptor:
241
+ # connection: TcpServer
242
+ # handler:
243
+ # collection: CollectionOfClients
244
+ #
245
+ #
246
+
247
+ @logger.info "DEFINE: Protocol::#{protocol}"
248
+
249
+ @protocol = LanGrove::ClassLoader.create( {
250
+
251
+ :module => 'Protocol',
252
+ :class => protocol
253
+
254
+ } )
255
+
256
+
172
257
  #
173
258
  # Notifiy the handler
174
259
  #
@@ -176,7 +261,6 @@ module LanGrove::Daemon class Base
176
261
  #
177
262
 
178
263
  @handler.start_daemon
179
-
180
264
 
181
265
  end
182
266
 
@@ -0,0 +1,90 @@
1
+ module LanGrove
2
+
3
+ class Find
4
+
5
+ def self.with( arg_hash , &block )
6
+
7
+ type = :file
8
+ @path = '.'
9
+
10
+ #
11
+ # TODO: filter
12
+ #
13
+
14
+ @incl = nil
15
+
16
+ @relative = false
17
+
18
+
19
+ arg_hash.each do |key, value|
20
+
21
+ case key
22
+
23
+ when :type
24
+
25
+ type = value
26
+
27
+ when :path
28
+
29
+ @path = value
30
+
31
+ when :include
32
+
33
+ @incl = value
34
+
35
+ when :relative
36
+
37
+ @relative = value
38
+
39
+ end
40
+
41
+
42
+ end
43
+
44
+ self.send( :"find_#{type}", @path, &block )
45
+
46
+ end
47
+
48
+ def self.find_file( path, &block )
49
+
50
+ puts "in #{path}"
51
+
52
+ Dir.entries( path ).each do | sub |
53
+
54
+ next if sub == '.'
55
+ next if sub == '..'
56
+
57
+ subdir = "#{path}/#{sub}"
58
+
59
+ begin
60
+
61
+ if @incl.nil? then
62
+
63
+ yield relative(subdir) if block
64
+
65
+ else
66
+
67
+ yield relative(subdir) unless /#{@incl}/.match( subdir ).nil?
68
+
69
+ end
70
+
71
+ next
72
+
73
+ end if File.file?( subdir ) and block
74
+
75
+ find_file( subdir, &block )
76
+
77
+ end
78
+
79
+ end
80
+
81
+ def self.relative( file_path )
82
+
83
+ return file_path.gsub( "#{@path}/",'' ) if @relative
84
+ return file_path
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -54,88 +54,95 @@ module LanGrove::Handler class Base
54
54
  def periodic
55
55
 
56
56
  #
57
- # TODO: There shall not only be one
58
- #
59
- # Changes are pending.
60
- #
61
- # OVERRIDE
57
+ # Call periodic on all clients
58
+ # in the collection
62
59
  #
63
- # To perform activities at the interval
64
- # defined in the config.
65
- #
60
+
61
+ @clients.each do |key, value|
62
+
63
+ if value == 1 then
64
+
65
+ key.periodic
66
+
67
+ next
68
+
69
+ end
70
+
71
+ value.periodic
72
+
73
+ end
66
74
 
67
75
  end
68
76
 
69
- def initialize( config_hash, daemon_name, logger )
70
-
71
- @config = config_hash
72
- @daemon_name = daemon_name
73
- @logger = logger
74
-
75
- @my_config = @config[ :daemons ][ @daemon_name ][ :handler ]
77
+ def connect( client )
76
78
 
77
- protocol = 'Base'
79
+ #
80
+ # A client has connected at the Adaptor
81
+ #
82
+ # It should be inserted into the collection
83
+ # of clients maintained here.
84
+ #
85
+ @logger.debug "Client::#{client} registers with Handler#{self}"
78
86
 
79
- if @my_config.has_key? :protocol then
87
+ if client.respond_to?( :unique_key ) then
80
88
 
81
- protocol = @my_config[ :protocol ]
89
+ @clients[ client.unique_key ] = client
90
+ return
82
91
 
83
92
  end
84
93
 
94
+ @clients[ client ] = 1
95
+
96
+ end
97
+
98
+ def disconnect( client )
99
+
85
100
  #
86
- # SIGNIFICANT DECISION
87
- #
88
- # - (currently) - There is one >>Instance<< of the protocol
101
+ # A client has disconnected
102
+ #
103
+ # It should be removed from the collection.
89
104
  #
90
- # - It is an object ( has .new )
105
+
91
106
  #
92
- # - All attached socket traffic is directed through it for de/encode
93
- # -
94
- # - ?.. ie. multiple TcpClients all routing through the same object..?
95
- # -
96
- # - THIS MAY NEED TO CHANGE (thinks & thinks & thinks)
107
+ # TODO: There will likely be a callback
108
+ # in the EM::Connection superclass
109
+ # that can be used here.
97
110
  #
98
- # - (Thinks) - It may move to the Client::Base so that each attached
99
- # client is paired with its own instance of the protocol.
111
+ # Client::Base extends EM::Connection
100
112
  #
101
- # - For now it wil be instanciated here and binded to each client at
102
- # connect - to be shared for the decoding. That should be fine for
103
- # as long as the protocol itself stores no state and is simply a
104
- # code path (Still, thinks & ...
105
- #
106
113
 
107
- #
108
- # initialize the protocol specified in config
109
- #
110
- # daemons:
111
- #
112
- # viking-invasion-early-warning-net_CoreHub_co_uk-D4RK1:
113
- #
114
- # adaptor:
115
- # connection: TriFocalOcularRotisserie
116
- # lightsource:
117
- # type: Fire
118
- # fuel: Peat
119
- #
120
- # handler:
121
- # collection: ScottishCoastalVillages
122
- # protocol: MedievalLanternMorse <----------
123
- #
124
- # Note: This is the application layer protocol
125
- # and is therefore entirely agnostic of
126
- # transport and disassociated from the
127
- # adapter in use.
128
- #
129
-
130
- @logger.info "Load definition: Protocol::#{protocol}"
114
+ @logger.info( "TODO: implement #{self.classname}disconnect()" )
131
115
 
132
- @protocol = LanGrove::ClassLoader.create( {
133
-
134
- :module => 'Protocol',
135
- :class => protocol
116
+ end
117
+
118
+ def initialize( config_hash, daemon_name, logger )
119
+
120
+ @config = config_hash
121
+ @daemon_name = daemon_name
122
+ @logger = logger
123
+
124
+ @clients = {}
125
+
126
+ begin
127
+
128
+ @logger.info "TODO: fall back to default Handler::Base"
136
129
 
137
- } )
130
+ @my_config = @config[ :daemons ][ @daemon_name ][ :handler ]
138
131
 
132
+ rescue
133
+
134
+ error = "Missing config item for daemon: #{@daemon_name}"
135
+
136
+ @logger.error "EXIT: #{error}"
137
+
138
+ raise LanGrove::DaemonConfigException.new(
139
+
140
+ "Missing config item for daemon: #{@daemon_name}"
141
+
142
+ )
143
+
144
+ end
145
+
139
146
  end
140
147
 
141
148
  end; end
@@ -1,3 +1,3 @@
1
1
  module LanGrove
2
- Version = VERSION = '0.0.4.3'
2
+ Version = VERSION = '0.0.4.4'
3
3
  end
@@ -1,6 +1,12 @@
1
1
  require 'langrove'
2
2
 
3
3
  describe 'A daemon' do
4
+
5
+ #
6
+ # HINT: tail -f functional/log/development.log
7
+ #
8
+ # To see this test in action.
9
+ #
4
10
 
5
11
  #
6
12
  # Use the demos in ./functional dir for integration tests
@@ -11,6 +11,7 @@ describe LanGrove::Daemon::Base do
11
11
  @adaptor_class = 'Base'
12
12
  @collection_class = 'Base'
13
13
  @client_class = 'Base'
14
+ @protocol_class = 'Base'
14
15
 
15
16
  @config = {
16
17
 
@@ -22,13 +23,20 @@ describe LanGrove::Daemon::Base do
22
23
 
23
24
  :adaptor => {
24
25
 
25
- :connection => @adaptor_class,
26
+ :connection => @adaptor_class
27
+
28
+ },
29
+
30
+ :client => {
31
+
32
+ :class => @client_class
33
+
34
+ },
35
+
36
+ :protocol => {
37
+
38
+ :class => @protocol_class
26
39
 
27
- :client => {
28
-
29
- :class => @client_class
30
-
31
- }
32
40
  },
33
41
 
34
42
  :handler => {
@@ -84,6 +92,38 @@ describe LanGrove::Daemon::Base do
84
92
 
85
93
  end
86
94
 
95
+ it 'loads the client defininition by config' do
96
+
97
+ client = subject.instance_variable_get( :@client )
98
+
99
+ client.should == LanGrove::Client::Base
100
+
101
+ end
102
+
103
+ it 'does not instanciate the client' do
104
+
105
+ client = subject.instance_variable_get( :@client )
106
+
107
+ client.should_not be_a(LanGrove::Client::Base)
108
+
109
+ end
110
+
111
+ it 'loads the protocol defininition by config' do
112
+
113
+ protocol = subject.instance_variable_get( :@protocol )
114
+
115
+ protocol.should == LanGrove::Protocol::Base
116
+
117
+ end
118
+
119
+ it 'does not instanciate the protocol' do
120
+
121
+ protocol = subject.instance_variable_get( :@protocol )
122
+
123
+ protocol.should_not be_a(LanGrove::Protocol::Base)
124
+
125
+ end
126
+
87
127
  it 'it schedules periodics'
88
128
 
89
129
  it 'when run, it calls to listen if server is true' do
@@ -0,0 +1,53 @@
1
+ require 'langrove/ext/find'
2
+
3
+ describe LanGrove::Find do
4
+
5
+ before :each do
6
+
7
+
8
+ @path = File.expand_path('../../../../bin', __FILE__ )
9
+
10
+ end
11
+
12
+ it 'searches finds' do
13
+
14
+ test = []
15
+
16
+ LanGrove::Find.with(
17
+
18
+ :type => :file,
19
+ :path => @path,
20
+ :relative => true
21
+
22
+ ) do |found|
23
+
24
+ test << found
25
+
26
+ end
27
+
28
+ test.length.should == 1
29
+ test[0].should == 'langrove'
30
+
31
+ end
32
+
33
+ it 'searches filters' do
34
+
35
+ test = []
36
+
37
+ LanGrove::Find.with(
38
+
39
+ :type => :file,
40
+ :path => @path,
41
+ :include => 'scotch mist'
42
+
43
+ ) do |found|
44
+
45
+ test << found
46
+
47
+ end
48
+
49
+ test.length.should == 0
50
+
51
+ end
52
+
53
+ end
@@ -24,34 +24,80 @@ describe LanGrove::Handler::Base do
24
24
 
25
25
  end
26
26
 
27
- context 'uses a protocol' do
27
+ subject do
28
28
 
29
- it 'that defaults to an instance of Protocol::Base' do
30
-
31
- test = LanGrove::Handler::Base.new( @config, @daemon_name, @logger )
29
+ LanGrove::Handler::Base.new( @config, @daemon_name, @logger )
30
+
31
+ end
32
+
33
+ context 'maintains a connected client collection with' do
34
+
35
+ it 'in a hash' do
32
36
 
33
- protocol = test.instance_variable_get( :@protocol )
37
+ clients = subject.instance_variable_get( :@clients )
34
38
 
35
- protocol.should == LanGrove::Protocol::Base
39
+ clients.should be_a( Hash )
36
40
 
37
41
  end
42
+
43
+ context 'connect()' do
38
44
 
39
- it 'as defined by the config_hash' do
45
+ it 'using a key defined by the client' do
46
+
47
+ client = double( 'Client' )
48
+ client.should_receive( :respond_to? ).with( :unique_key ).and_return( true )
49
+ client.should_receive( :unique_key ).and_return('KEY1')
50
+
51
+ subject.connect( client )
52
+
53
+ clients = subject.instance_variable_get( :@clients )
54
+
55
+ clients['KEY1'].should == client
56
+
57
+ end
40
58
 
41
- @config[:daemons][@daemon_name][:handler][:protocol] = 'MedievalLanternMorse'
59
+ it 'using the client itself as the key if unique is not defined' do
60
+
61
+ client = double( 'Client' )
62
+ client.should_receive( :respond_to? ).with( :unique_key ).and_return( false )
63
+
64
+ subject.connect( client )
65
+
66
+ clients = subject.instance_variable_get( :@clients )
67
+
68
+ clients[ client ].should == 1
69
+
70
+ end
42
71
 
43
- expect {
72
+ end
73
+
74
+ context 'disconnect()' do
44
75
 
45
- test = LanGrove::Handler::Base.new( @config, @daemon_name, @logger )
76
+ it 'to remove the client from the collection'
46
77
 
47
- }.to raise_error( LanGrove::ClassLoaderException,
78
+ end
79
+
80
+ it 'call the periodic ticker to all attached clients' do
48
81
 
49
- "no such file to load -- protocol/medieval_lantern_morse.rb"
82
+ client1 = Object.const_set( 'Client', Class.new() do
83
+
84
+ self.class_eval { attr_accessor :unique }
50
85
 
51
- )
86
+ end).new
87
+ client1.unique = 'kEy'
88
+
89
+ client2 = Object.new
90
+
91
+ client1.should_receive( :periodic )
92
+ client2.should_receive( :periodic )
93
+
94
+ subject.connect( client1 )
95
+ subject.connect( client2 )
96
+
97
+ subject.periodic
52
98
 
53
99
  end
54
100
 
55
101
  end
56
-
102
+
57
103
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langrove
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4.3
4
+ version: 0.0.4.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,11 +12,11 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-04-23 00:00:00.000000000Z
15
+ date: 2012-04-24 00:00:00.000000000Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: watchr
19
- requirement: &70168446729980 !ruby/object:Gem::Requirement
19
+ requirement: &2153525920 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
22
  - - ! '>='
@@ -24,10 +24,10 @@ dependencies:
24
24
  version: '0'
25
25
  type: :development
26
26
  prerelease: false
27
- version_requirements: *70168446729980
27
+ version_requirements: *2153525920
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rspec
30
- requirement: &70168446729480 !ruby/object:Gem::Requirement
30
+ requirement: &2153525420 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
33
  - - ~>
@@ -35,10 +35,10 @@ dependencies:
35
35
  version: '2.9'
36
36
  type: :development
37
37
  prerelease: false
38
- version_requirements: *70168446729480
38
+ version_requirements: *2153525420
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: rake
41
- requirement: &70168446728960 !ruby/object:Gem::Requirement
41
+ requirement: &2153524900 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
44
  - - ~>
@@ -49,10 +49,10 @@ dependencies:
49
49
  version: 0.8.7
50
50
  type: :development
51
51
  prerelease: false
52
- version_requirements: *70168446728960
52
+ version_requirements: *2153524900
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: eventmachine
55
- requirement: &70168446728220 !ruby/object:Gem::Requirement
55
+ requirement: &2153524160 !ruby/object:Gem::Requirement
56
56
  none: false
57
57
  requirements:
58
58
  - - ~>
@@ -63,10 +63,10 @@ dependencies:
63
63
  version: 0.12.10
64
64
  type: :runtime
65
65
  prerelease: false
66
- version_requirements: *70168446728220
66
+ version_requirements: *2153524160
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: em-http-request
69
- requirement: &70168446727480 !ruby/object:Gem::Requirement
69
+ requirement: &2153523420 !ruby/object:Gem::Requirement
70
70
  none: false
71
71
  requirements:
72
72
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 0.3.0
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *70168446727480
80
+ version_requirements: *2153523420
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: daemon-kit
83
- requirement: &70168446726740 !ruby/object:Gem::Requirement
83
+ requirement: &2153522680 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ~>
@@ -91,10 +91,10 @@ dependencies:
91
91
  version: 0.1.8.2
92
92
  type: :runtime
93
93
  prerelease: false
94
- version_requirements: *70168446726740
94
+ version_requirements: *2153522680
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: resque
97
- requirement: &70168446726000 !ruby/object:Gem::Requirement
97
+ requirement: &2153521940 !ruby/object:Gem::Requirement
98
98
  none: false
99
99
  requirements:
100
100
  - - ~>
@@ -105,7 +105,7 @@ dependencies:
105
105
  version: 1.20.0
106
106
  type: :runtime
107
107
  prerelease: false
108
- version_requirements: *70168446726000
108
+ version_requirements: *2153521940
109
109
  description: ''
110
110
  email: richard@clue.co.za
111
111
  executables:
@@ -120,20 +120,17 @@ files:
120
120
  - .rvmrc
121
121
  - .watchr
122
122
  - Rakefile
123
- - functional/.gitignore
124
- - functional/bin/datagram
125
- - functional/config/.gitignore
123
+ - tmp/README
126
124
  - functional/config/boot.rb
127
125
  - functional/config/daemons.yml
128
126
  - functional/config/environment.rb
129
127
  - functional/config/environments/development.rb
130
128
  - functional/config/environments/production.rb
131
129
  - functional/config/environments/test.rb
130
+ - functional/lib/client/socket_to_file.rb
132
131
  - functional/lib/daemon/datagram.rb
133
- - functional/lib/handler/socket_to_file.rb
134
132
  - functional/lib/protocol/socket_to_file.rb
135
133
  - functional/libexec/daemon.rb
136
- - functional/log/.gitignore
137
134
  - functional/tmp/README
138
135
  - lib/langrove/_base.rb
139
136
  - lib/langrove/adaptor/base.rb
@@ -148,6 +145,7 @@ files:
148
145
  - lib/langrove/ext/config_item.rb
149
146
  - lib/langrove/ext/config_loader.rb
150
147
  - lib/langrove/ext/fake_logger.rb
148
+ - lib/langrove/ext/find.rb
151
149
  - lib/langrove/ext/persistable.rb
152
150
  - lib/langrove/ext/string.rb
153
151
  - lib/langrove/ext.rb
@@ -168,13 +166,13 @@ files:
168
166
  - spec/langrove/ext/config_item_spec.rb
169
167
  - spec/langrove/ext/config_loader_spec.rb
170
168
  - spec/langrove/ext/fake_logger_spec.rb
169
+ - spec/langrove/ext/find_spec.rb
171
170
  - spec/langrove/ext/persistable_spec.rb
172
171
  - spec/langrove/ext/string_spec.rb
173
172
  - spec/langrove/handler_base_spec.rb
174
173
  - spec/langrove/protocol/syslog_spec.rb
175
174
  - spec/langrove/protocol_base_spec.rb
176
175
  - spec/todo_spec.rb
177
- - tmp/README
178
176
  homepage: ''
179
177
  licenses: []
180
178
  post_install_message:
@@ -195,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
193
  version: '0'
196
194
  requirements: []
197
195
  rubyforge_project:
198
- rubygems_version: 1.8.10
196
+ rubygems_version: 1.8.8
199
197
  signing_key:
200
198
  specification_version: 3
201
199
  summary: eventmachine based networked daemon framework
@@ -1 +0,0 @@
1
- tmp/*.*
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- DAEMON_ROOT = File.expand_path('../../../functional/', __FILE__)
4
- DAEMON_NAME = File.basename $0
5
- require File.expand_path('../../config/environment', __FILE__)
6
- DaemonKit::Application.exec( DAEMON_ROOT + '/libexec/daemon.rb' )
File without changes
@@ -1,42 +0,0 @@
1
- #
2
- # Define a Handler by extending LanGrove::Handler::Base
3
- # and extending the functions:
4
- #
5
- # 1. <YourClass>.receive( data )
6
- #
7
- # Data arriving from the Adaptor will arrive into
8
- # this function having already been decoded by the
9
- # configured Protocol for this Handler
10
- #
11
- # # 2. <YourClass>.transmit
12
- # #
13
-
14
- require 'langrove'
15
-
16
- module Handler
17
-
18
- class SocketToFile < LanGrove::Handler::Base
19
-
20
- def periodic
21
-
22
- @logger.info( "periodic" )
23
-
24
- end
25
-
26
- def receive( data )
27
-
28
- @logger.info( "#{self}.receive: #{data}" )
29
-
30
- File.open( data[:filename], 'w' ) do |f|
31
-
32
- f.write( data[:content] )
33
-
34
- end
35
-
36
- @logger.info "Wrote data: '#{data[ :content ]}' to file: '#{ data[ :filename ]}'"
37
-
38
- end
39
-
40
- end
41
-
42
- end
@@ -1,3 +0,0 @@
1
- *.log
2
- *.pid
3
- *.yml