arborist 0.0.1.pre20160106113421

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.simplecov +9 -0
  4. data/ChangeLog +417 -0
  5. data/Events.md +20 -0
  6. data/History.md +4 -0
  7. data/LICENSE +29 -0
  8. data/Manifest.txt +72 -0
  9. data/Monitors.md +141 -0
  10. data/Nodes.md +0 -0
  11. data/Observers.md +72 -0
  12. data/Protocol.md +214 -0
  13. data/README.md +75 -0
  14. data/Rakefile +81 -0
  15. data/TODO.md +24 -0
  16. data/bin/amanagerd +10 -0
  17. data/bin/amonitord +12 -0
  18. data/bin/aobserverd +12 -0
  19. data/lib/arborist.rb +182 -0
  20. data/lib/arborist/client.rb +191 -0
  21. data/lib/arborist/event.rb +61 -0
  22. data/lib/arborist/event/node_acked.rb +18 -0
  23. data/lib/arborist/event/node_delta.rb +20 -0
  24. data/lib/arborist/event/node_matching.rb +34 -0
  25. data/lib/arborist/event/node_update.rb +19 -0
  26. data/lib/arborist/event/sys_reloaded.rb +15 -0
  27. data/lib/arborist/exceptions.rb +21 -0
  28. data/lib/arborist/manager.rb +508 -0
  29. data/lib/arborist/manager/event_publisher.rb +97 -0
  30. data/lib/arborist/manager/tree_api.rb +207 -0
  31. data/lib/arborist/mixins.rb +363 -0
  32. data/lib/arborist/monitor.rb +377 -0
  33. data/lib/arborist/monitor/socket.rb +163 -0
  34. data/lib/arborist/monitor_runner.rb +217 -0
  35. data/lib/arborist/node.rb +700 -0
  36. data/lib/arborist/node/host.rb +87 -0
  37. data/lib/arborist/node/root.rb +60 -0
  38. data/lib/arborist/node/service.rb +112 -0
  39. data/lib/arborist/observer.rb +176 -0
  40. data/lib/arborist/observer/action.rb +125 -0
  41. data/lib/arborist/observer/summarize.rb +105 -0
  42. data/lib/arborist/observer_runner.rb +181 -0
  43. data/lib/arborist/subscription.rb +82 -0
  44. data/spec/arborist/client_spec.rb +282 -0
  45. data/spec/arborist/event/node_update_spec.rb +71 -0
  46. data/spec/arborist/event_spec.rb +64 -0
  47. data/spec/arborist/manager/event_publisher_spec.rb +66 -0
  48. data/spec/arborist/manager/tree_api_spec.rb +458 -0
  49. data/spec/arborist/manager_spec.rb +442 -0
  50. data/spec/arborist/mixins_spec.rb +195 -0
  51. data/spec/arborist/monitor/socket_spec.rb +195 -0
  52. data/spec/arborist/monitor_runner_spec.rb +152 -0
  53. data/spec/arborist/monitor_spec.rb +251 -0
  54. data/spec/arborist/node/host_spec.rb +104 -0
  55. data/spec/arborist/node/root_spec.rb +29 -0
  56. data/spec/arborist/node/service_spec.rb +98 -0
  57. data/spec/arborist/node_spec.rb +552 -0
  58. data/spec/arborist/observer/action_spec.rb +205 -0
  59. data/spec/arborist/observer/summarize_spec.rb +294 -0
  60. data/spec/arborist/observer_spec.rb +146 -0
  61. data/spec/arborist/subscription_spec.rb +71 -0
  62. data/spec/arborist_spec.rb +146 -0
  63. data/spec/data/monitors/pings.rb +80 -0
  64. data/spec/data/monitors/port_checks.rb +27 -0
  65. data/spec/data/monitors/system_resources.rb +30 -0
  66. data/spec/data/monitors/web_services.rb +17 -0
  67. data/spec/data/nodes/duir.rb +20 -0
  68. data/spec/data/nodes/localhost.rb +15 -0
  69. data/spec/data/nodes/sidonie.rb +29 -0
  70. data/spec/data/nodes/yevaud.rb +26 -0
  71. data/spec/data/observers/auditor.rb +23 -0
  72. data/spec/data/observers/webservices.rb +18 -0
  73. data/spec/spec_helper.rb +117 -0
  74. metadata +368 -0
@@ -0,0 +1,75 @@
1
+ # Arborist
2
+
3
+ home :: http://deveiate.org/projects/Arborist
4
+ code :: http://bitbucket.org/ged/Arborist
5
+ github :: https://github.com/ged/arborist
6
+ docs :: http://deveiate.org/code/arborist
7
+
8
+
9
+ ## Description
10
+
11
+ Arborist is a monitoring framework that follows the UNIX philosophy
12
+ of small parts and loose coupling for stability, reliability, and
13
+ customizability.
14
+
15
+
16
+ ## Prerequisites
17
+
18
+ * Ruby 2.2 or better
19
+
20
+
21
+ ## Installation
22
+
23
+ $ gem install arborist
24
+
25
+
26
+ ## Further Reading
27
+
28
+ You'll likely want to start with [the Tutorial](Tutorial.html).
29
+
30
+
31
+ ## Contributing
32
+
33
+ You can check out the current development source with Mercurial via its
34
+ [project page](http://bitbucket.org/ged/Arborist). Or if you prefer Git, via
35
+ [its Github mirror](https://github.com/ged/arborist).
36
+
37
+ After checking out the source, run:
38
+
39
+ $ rake newb
40
+
41
+ This task will install any missing dependencies, run the tests/specs,
42
+ and generate the API documentation.
43
+
44
+
45
+ ## License
46
+
47
+ Copyright (c) 2015, Michael Granger and Mahlon E. Smith
48
+ All rights reserved.
49
+
50
+ Redistribution and use in source and binary forms, with or without
51
+ modification, are permitted provided that the following conditions are met:
52
+
53
+ * Redistributions of source code must retain the above copyright notice,
54
+ this list of conditions and the following disclaimer.
55
+
56
+ * Redistributions in binary form must reproduce the above copyright notice,
57
+ this list of conditions and the following disclaimer in the documentation
58
+ and/or other materials provided with the distribution.
59
+
60
+ * Neither the name of the author/s, nor the names of the project's
61
+ contributors may be used to endorse or promote products derived from this
62
+ software without specific prior written permission.
63
+
64
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
65
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
67
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
68
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
70
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
71
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
72
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
73
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74
+
75
+
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'hoe'
5
+ rescue LoadError
6
+ abort "This Rakefile requires hoe (gem install hoe)"
7
+ end
8
+
9
+ GEMSPEC = 'arborist.gemspec'
10
+
11
+
12
+ Hoe.plugin :mercurial
13
+ Hoe.plugin :signing
14
+ Hoe.plugin :deveiate
15
+
16
+ Hoe.plugins.delete :rubyforge
17
+ Hoe.plugins.delete :gemcutter
18
+
19
+ hoespec = Hoe.spec 'arborist' do |spec|
20
+ spec.readme_file = 'README.md'
21
+ spec.history_file = 'History.md'
22
+ spec.extra_rdoc_files = FileList[ '*.rdoc', '*.md' ]
23
+ self.license 'BSD-3-Clause'
24
+ spec.urls = {
25
+ home: 'http://deveiate.org/projects/arborist',
26
+ code: 'http://bitbucket.org/ged/arborist',
27
+ docs: 'http://deveiate.org/code/arborist',
28
+ github: 'http://github.com/ged/arborist',
29
+ }
30
+
31
+ spec.developer 'Michael Granger', 'ged@FaerieMUD.org'
32
+ spec.developer 'Mahlon E. Smith', 'mahlon@martini.nu'
33
+
34
+ spec.dependency 'schedulability', '~> 0.1'
35
+ spec.dependency 'loggability', '~> 0.11'
36
+ spec.dependency 'configurability', '~> 2.2'
37
+ spec.dependency 'pluggability', '~> 0.4'
38
+ spec.dependency 'state_machines', '~> 0.2'
39
+ spec.dependency 'msgpack', '~> 0.6'
40
+ spec.dependency 'rbczmq', '~> 1.7'
41
+
42
+ spec.dependency 'rspec', '~> 3.2', :developer
43
+ spec.dependency 'simplecov', '~> 0.9', :developer
44
+ spec.dependency 'timecop', '~> 0.7', :developer
45
+
46
+ spec.require_ruby_version( '>=2.2.0' )
47
+ spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
48
+
49
+ self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
50
+ end
51
+
52
+
53
+ ENV['VERSION'] ||= hoespec.spec.version.to_s
54
+
55
+ # Run the tests before checking in
56
+ task 'hg:precheckin' => [ :check_history, :check_manifest, :gemspec, :spec ]
57
+
58
+ # Rebuild the ChangeLog immediately before release
59
+ task :prerelease => 'ChangeLog'
60
+ CLOBBER.include( 'ChangeLog' )
61
+
62
+ desc "Build a coverage report"
63
+ task :coverage do
64
+ ENV["COVERAGE"] = 'yes'
65
+ Rake::Task[:spec].invoke
66
+ end
67
+
68
+
69
+ task :gemspec => GEMSPEC
70
+ file GEMSPEC => __FILE__ do |task|
71
+ spec = $hoespec.spec
72
+ spec.files.delete( '.gemtest' )
73
+ spec.signing_key = nil
74
+ spec.version = "#{spec.version}.pre#{Time.now.strftime("%Y%m%d%H%M%S")}"
75
+ File.open( task.name, 'w' ) do |fh|
76
+ fh.write( spec.to_ruby )
77
+ end
78
+ end
79
+
80
+ task :default => :gemspec
81
+
data/TODO.md ADDED
@@ -0,0 +1,24 @@
1
+ # To-Do
2
+
3
+ ## Manager
4
+
5
+ * Serialize nodes on shutdown
6
+ * Include a node's subscriptions in its serialized data
7
+ * Implement loading/reloading nodes.
8
+
9
+ ## Tree API
10
+
11
+ * Add "grafting": node add/removal
12
+
13
+ ## Observers
14
+
15
+ * Scheduling time periods for action/summarizing
16
+ * Summarizing and Actions should be 1st order objects
17
+ * Unsubscribe from Arborist and ZMQ subscriptions on shutdown
18
+ * Figure out how to match on delta events: the criteria
19
+ for matching nodes has to be separated from that which matches
20
+ the delta pairs.
21
+
22
+ ## Node
23
+
24
+ * Add a 'disabled' state, can be set on 'up' nodes by acking them.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arborist'
4
+ require 'arborist/manager'
5
+
6
+ $0 = "Arborist::Manager"
7
+
8
+ Arborist.load_config( ARGV.pop )
9
+ mgr = Arborist.manager_for( ARGV.shift )
10
+ mgr.run
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arborist'
4
+ require 'arborist/monitor_runner'
5
+
6
+ monitors_path = ARGV.shift or raise "No monitor file specified."
7
+
8
+ Arborist.load_config( ARGV.shift )
9
+ Arborist.load_all
10
+
11
+ runner = Arborist.monitor_runner_for( monitors_path )
12
+ runner.run
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arborist'
4
+ require 'arborist/observer_runner'
5
+
6
+ observers_path = ARGV.shift or raise "No observer file specified."
7
+
8
+ Arborist.load_config( ARGV.shift )
9
+ Arborist.load_all
10
+
11
+ runner = Arborist.observer_runner_for( observers_path )
12
+ runner.run
@@ -0,0 +1,182 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'rbczmq'
5
+
6
+ require 'pathname'
7
+ require 'configurability'
8
+ require 'loggability'
9
+
10
+
11
+ # Arborist namespace
12
+ module Arborist
13
+ extend Loggability,
14
+ Configurability
15
+
16
+ # Package version
17
+ VERSION = '0.0.1'
18
+
19
+ # Version control revision
20
+ REVISION = %q$Revision: fddcbace9b6d $
21
+
22
+
23
+ # The name of the environment variable which can be used to set the config path
24
+ CONFIG_ENV = 'ARBORIST_CONFIG'
25
+
26
+ # The name of the config file for local overrides.
27
+ LOCAL_CONFIG_FILE = Pathname( '~/.arborist.yml' ).expand_path
28
+
29
+ # The name of the config file that's loaded if none is specified.
30
+ DEFAULT_CONFIG_FILE = Pathname( 'arborist.yml' ).expand_path
31
+
32
+ # Configurability API -- default configuration values
33
+ CONFIG_DEFAULTS = {
34
+ tree_api_url: 'ipc:///tmp/arborist_tree.sock',
35
+ event_api_url: 'ipc:///tmp/arborist_events.sock'
36
+ }
37
+
38
+
39
+ ##
40
+ # Set up a logger for the Arborist namespace
41
+ log_as :arborist
42
+
43
+ # Configurability API -- use the 'arborist'
44
+ config_key :arborist
45
+
46
+
47
+ require 'arborist/mixins'
48
+ extend Arborist::MethodUtilities
49
+
50
+
51
+ ##
52
+ # The ZMQ REP socket for the API for accessing the node tree.
53
+ singleton_attr_accessor :tree_api_url
54
+ @tree_api_url = CONFIG_DEFAULTS[ :tree_api_url ]
55
+
56
+ ##
57
+ # The ZMQ PUB socket for published events
58
+ singleton_attr_accessor :event_api_url
59
+ @event_api_url = CONFIG_DEFAULTS[ :event_api_url ]
60
+
61
+
62
+ #
63
+ # :section: Configuration API
64
+ #
65
+
66
+ ### Configurability API.
67
+ def self::configure( config=nil )
68
+ config = self.defaults.merge( config || {} )
69
+
70
+ self.tree_api_url = config[ :tree_api_url ]
71
+ self.event_api_url = config[ :event_api_url ]
72
+ end
73
+
74
+
75
+ ### Get the loaded config (a Configurability::Config object)
76
+ def self::config
77
+ Configurability.loaded_config
78
+ end
79
+
80
+
81
+ ### Returns +true+ if the configuration has been loaded at least once.
82
+ def self::config_loaded?
83
+ return self.config ? true : false
84
+ end
85
+
86
+
87
+ ### Load the specified +config_file+, install the config in all objects with
88
+ ### Configurability, and call any callbacks registered via #after_configure.
89
+ def self::load_config( config_file=nil, defaults=nil )
90
+ config_file ||= ENV[ CONFIG_ENV ]
91
+ config_file ||= LOCAL_CONFIG_FILE if LOCAL_CONFIG_FILE.exist?
92
+ config_file ||= DEFAULT_CONFIG_FILE
93
+
94
+ defaults ||= Configurability.gather_defaults
95
+
96
+ self.log.info "Loading config from %p with defaults for sections: %p." %
97
+ [ config_file, defaults.keys ]
98
+ config = Configurability::Config.load( config_file, defaults )
99
+
100
+ config.install
101
+ end
102
+
103
+
104
+ ### Add a constructor function to the Arborist namespace called +name+
105
+ ### with the specified +method_body+.
106
+ def self::add_dsl_constructor( name, &method_body )
107
+ self.log.debug "Adding constructor for %p: %p" % [ name, method_body ]
108
+ singleton_class.instance_exec( name, method_body ) do |name, body|
109
+ define_method( name, &body )
110
+ end
111
+ end
112
+
113
+
114
+ ### Return a new Arborist::Manager for the nodes described in files under
115
+ ### the specified +directory+.
116
+ def self::manager_for( directory )
117
+ self.load_all
118
+ nodes = Arborist::Node.each_in( directory )
119
+ manager = Arborist::Manager.new
120
+ manager.load_tree( nodes )
121
+
122
+ return manager
123
+ end
124
+
125
+
126
+ ### Return a new Arborist::MonitorRunner for the monitors described in files under
127
+ ### the specified +directory+.
128
+ def self::monitor_runner_for( directory )
129
+ self.load_all
130
+ monitors = Arborist::Monitor.each_in( directory )
131
+ runner = Arborist::MonitorRunner.new
132
+ runner.load_monitors( monitors )
133
+
134
+ return runner
135
+ end
136
+
137
+
138
+ ### Return a new Arborist::ObserverRunner for the observers described in files under
139
+ ### the specified +directory+.
140
+ def self::observer_runner_for( directory )
141
+ self.load_all
142
+ observers = Arborist::Observer.each_in( directory )
143
+ runner = Arborist::ObserverRunner.new
144
+ runner.load_observers( observers )
145
+
146
+ return runner
147
+ end
148
+
149
+
150
+ ### Load all node and event types
151
+ def self::load_all
152
+ Arborist::Node.load_all
153
+ end
154
+
155
+
156
+ ### Destroy any existing ZMQ state.
157
+ def self::reset_zmq_context
158
+ @zmq_context.destroy if @zmq_context.respond_to?( :destroy )
159
+ @zmq_context = nil
160
+ end
161
+
162
+
163
+ ### Fetch the ZMQ context for Arborist.
164
+ def self::zmq_context
165
+ return @zmq_context ||= ZMQ::Context.new
166
+ end
167
+
168
+
169
+ require 'arborist/exceptions'
170
+ require 'arborist/mixins'
171
+
172
+ autoload :Client, 'arborist/client'
173
+ autoload :Event, 'arborist/event'
174
+ autoload :Manager, 'arborist/manager'
175
+ autoload :Monitor, 'arborist/monitor'
176
+ autoload :MonitorRunner, 'arborist/monitor_runner'
177
+ autoload :Node, 'arborist/node'
178
+ autoload :Observer, 'arborist/observer'
179
+ autoload :Subscription, 'arborist/subscription'
180
+
181
+ end # module Arborist
182
+
@@ -0,0 +1,191 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'arborist' unless defined?( Arborist )
5
+ require 'msgpack'
6
+
7
+
8
+ # Unified Arborist Manager client for both the Tree and Event APIs
9
+ class Arborist::Client
10
+ extend Loggability
11
+
12
+ # The version of the client.
13
+ API_VERSION = 1
14
+
15
+ # Loggability API -- log to the Arborist log host
16
+ log_to :arborist
17
+
18
+
19
+ ### Create a new Client with the given API socket URIs.
20
+ def initialize( tree_api_url: nil, event_api_url: nil )
21
+ @tree_api_url = tree_api_url || Arborist.tree_api_url
22
+ @event_api_url = event_api_url || Arborist.event_api_url
23
+
24
+ @request_queue = nil
25
+ @event_subscriptions = nil
26
+ end
27
+
28
+
29
+ ######
30
+ public
31
+ ######
32
+
33
+ # The ZMQ URI required to speak to the Arborist tree API.
34
+ attr_accessor :tree_api_url
35
+
36
+ # The ZMQ URI required to speak to the Arborist event API.
37
+ attr_accessor :event_api_url
38
+
39
+
40
+ ### Return the manager's current status as a hash.
41
+ def status
42
+ request = self.make_status_request
43
+ return self.send_tree_api_request( request )
44
+ end
45
+
46
+
47
+ ### Return the manager's current status as a hash.
48
+ def make_status_request
49
+ return self.pack_message( :status )
50
+ end
51
+
52
+
53
+ ### Return the manager's current node tree.
54
+ def list( *args )
55
+ request = self.make_list_request( *args )
56
+ return self.send_tree_api_request( request )
57
+ end
58
+
59
+
60
+ ### Return the manager's current node tree.
61
+ def make_list_request( from: nil )
62
+ header = {}
63
+ self.log.debug "From is: %p" % [ from ]
64
+ header[:from] = from if from
65
+
66
+ return self.pack_message( :list, header )
67
+ end
68
+
69
+
70
+ ### Return the manager's current node tree.
71
+ def fetch( criteria={}, *args )
72
+ request = self.make_fetch_request( criteria, *args )
73
+ return self.send_tree_api_request( request )
74
+ end
75
+
76
+
77
+ ### Return the manager's current node tree.
78
+ def make_fetch_request( criteria, include_down: false, properties: :all )
79
+ header = {}
80
+ header[ :include_down ] = true if include_down
81
+ header[ :return ] = properties if properties != :all
82
+
83
+ return self.pack_message( :fetch, header, criteria )
84
+ end
85
+
86
+
87
+ ### Update the identified nodes in the manager with the specified data.
88
+ def update( *args )
89
+ request = self.make_update_request( *args )
90
+ return self.send_tree_api_request( request )
91
+ end
92
+
93
+
94
+ ### Update the identified nodes in the manager with the specified data.
95
+ def make_update_request( data )
96
+ return self.pack_message( :update, nil, data )
97
+ end
98
+
99
+
100
+ ### Add a subscription
101
+ def subscribe( *args )
102
+ request = self.make_subscribe_request( *args )
103
+ response = self.send_tree_api_request( request )
104
+ return response.first
105
+ end
106
+
107
+
108
+ ### Make a subscription request for the specified +criteria+, +identifier+, and +event_type+.
109
+ def make_subscribe_request( criteria: {}, identifier: nil, event_type: nil )
110
+ self.log.debug "Making subscription request for identifier: %p, event_type: %p, criteria: %p" %
111
+ [ identifier, event_type, criteria ]
112
+ header = {}
113
+ header[ :identifier ] = identifier if identifier
114
+ header[ :event_type ] = event_type
115
+
116
+ return self.pack_message( :subscribe, header, criteria )
117
+ end
118
+
119
+
120
+ ### Send the packed +request+ via the Tree API socket, raise an error on
121
+ ### unsuccessful response, and return the response body.
122
+ def send_tree_api_request( request )
123
+ self.log.debug "Sending request: %p" % [ request ]
124
+ self.tree_api.send( request )
125
+
126
+ res = self.tree_api.recv
127
+ self.log.debug "Received response: %p" % [ res ]
128
+
129
+ header, body = self.unpack_message( res )
130
+ unless header[ 'success' ]
131
+ raise "Arborist manager said: %s" % [ header['reason'] ]
132
+ end
133
+
134
+ return body
135
+ end
136
+
137
+
138
+
139
+ ### Format ruby +data+ for communicating with the Arborist manager.
140
+ def pack_message( verb, *data )
141
+ header = data.shift || {}
142
+ body = data.shift
143
+
144
+ header.merge!( action: verb, version: API_VERSION )
145
+
146
+ self.log.debug "Packing message; header: %p, body: %p" % [ header, body ]
147
+
148
+ return MessagePack.pack([ header, body ])
149
+ end
150
+
151
+
152
+ ### De-serialize an Arborist manager response.
153
+ def unpack_message( msg )
154
+ return MessagePack.unpack( msg )
155
+ end
156
+
157
+
158
+ ### Return a ZMQ REQ socket connected to the manager's tree API, instantiating
159
+ ### it if necessary.
160
+ def tree_api
161
+ return @tree_api ||= self.make_tree_api_socket
162
+ end
163
+
164
+
165
+ ### Create a new ZMQ REQ socket connected to the manager's tree API.
166
+ def make_tree_api_socket
167
+ self.log.info "Connecting to the tree socket %p" % [ self.tree_api_url ]
168
+ sock = Arborist.zmq_context.socket( :REQ )
169
+ sock.connect( self.tree_api_url )
170
+
171
+ return sock
172
+ end
173
+
174
+
175
+ ### Return a ZMQ SUB socket connected to the manager's event API, instantiating
176
+ ### it if necessary.
177
+ def event_api
178
+ return @event_api ||= self.make_event_api_socket
179
+ end
180
+
181
+
182
+ ### Create a new ZMQ SUB socket connected to the manager's event API.
183
+ def make_event_api_socket
184
+ self.log.info "Connecting to the event socket %p" % [ self.event_api_url ]
185
+ sock = Arborist.zmq_context.socket( :SUB )
186
+ sock.connect( self.event_api_url )
187
+
188
+ return sock
189
+ end
190
+
191
+ end # class Arborist::Client