langrove 0.0.5.3 → 0.0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +18 -16
- data/langrove.gemspec +1 -0
- data/lib/langrove/README.md +9 -9
- data/lib/langrove/adaptor/README.md +1 -1
- data/lib/langrove/behaviour/README.md +15 -15
- data/lib/langrove/daemon/daemon_base.rb +8 -1
- data/lib/langrove/ext/fake_root.rb +2 -0
- data/lib/langrove/ext/log_monitor.rb +227 -1
- data/lib/langrove/handler/README.md +5 -5
- data/lib/langrove/plugin/README.md +5 -5
- data/lib/langrove/plugin/persistor.rb +1 -1
- data/lib/langrove/plugin/yaml_file.rb +1 -1
- data/lib/langrove/protocol/README.md +2 -2
- data/lib/langrove/root/README.md +40 -1
- data/lib/langrove/root/base.rb +1 -0
- data/lib/langrove/root/config.rb +35 -0
- data/lib/langrove/root/metrix.rb +204 -0
- data/lib/langrove/root/root_base.rb +3 -15
- data/lib/langrove/version.rb +1 -1
- data/spec/langrove/root/metrix_spec.rb +60 -0
- data/spec/spec_helper.rb +3 -1
- metadata +4 -4
- data/.rspec +0 -1
- data/.rvmrc +0 -53
data/README.md
CHANGED
@@ -3,9 +3,18 @@ LanGrove
|
|
3
3
|
|
4
4
|
[LanGrove](http://www.google.com/search?hl=en&safe=off&biw=1065&bih=884&tbm=isch&sa=1&q=mangrove&btnG=) levarages [EventMachine](http://eventmachine.rubyforge.org/EventMachine.html) and [DaemonKit](https://github.com/kennethkalmer/daemon-kit/) to provide a framework for quick to implement network aware systems by providing an easily configurable transport and session layer and exposing generic interfaces into the application layer.
|
5
5
|
|
6
|
-
### Getting started quickly with [Scaffold and Configuration](https://github.com/cluetechnologies/langrove
|
6
|
+
### Getting started quickly with [Scaffold and Configuration](https://github.com/cluetechnologies/langrove/tree/master/bin)
|
7
|
+
|
8
|
+
### Understanding the [Framework Components](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove)
|
9
|
+
|
10
|
+
|
11
|
+
Note to Developers
|
12
|
+
------------------
|
13
|
+
|
14
|
+
* Uses [Guard](https://github.com/guard/guard/) to watch for changes in `lib` or `spec` directories
|
15
|
+
* Runs specs accordingly.
|
16
|
+
* `bundle exec guard`
|
7
17
|
|
8
|
-
### Understanding the [Framework Components](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove)
|
9
18
|
|
10
19
|
Change Log
|
11
20
|
----------
|
@@ -13,22 +22,15 @@ Change Log
|
|
13
22
|
### 2012-08-08
|
14
23
|
|
15
24
|
* v0.0.5.3
|
25
|
+
* Started on `Metrix` (introspection subsystem)
|
16
26
|
|
27
|
+
### 2012-08-09
|
17
28
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
* Rename this to `langrove`
|
22
|
-
* Rename the original to `langrove-enterprise`
|
23
|
-
* Swing all document links
|
24
|
-
* Publish this repo
|
25
|
-
* Start on the Enterprise Extensions
|
26
|
-
|
29
|
+
* Create metrix daemon component sampler infrastructure
|
30
|
+
* v0.0.5.4
|
27
31
|
|
28
|
-
Note to Developers
|
29
|
-
------------------
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
* `bundle exec guard`
|
33
|
+
TODO
|
34
|
+
----
|
34
35
|
|
36
|
+
* Pass all config queries through single interface
|
data/langrove.gemspec
CHANGED
data/lib/langrove/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Foundation
|
2
2
|
==========
|
3
3
|
|
4
|
-
### [Langrove::Root::Base](https://github.com/cluetechnologies/langrove
|
4
|
+
### [Langrove::Root::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/root)
|
5
5
|
|
6
6
|
Provides the `Config` and `Logger`.
|
7
7
|
|
8
|
-
### [LanGrove::Daemon::Base](https://github.com/cluetechnologies/langrove
|
8
|
+
### [LanGrove::Daemon::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/daemon)
|
9
9
|
|
10
10
|
Defines the `Container` that houses the Primary Daemon Components
|
11
11
|
|
@@ -14,22 +14,22 @@ Primary Components
|
|
14
14
|
==================
|
15
15
|
|
16
16
|
|
17
|
-
### [LanGrove::Adaptor::Base](https://github.com/cluetechnologies/langrove
|
17
|
+
### [LanGrove::Adaptor::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/adaptor)
|
18
18
|
|
19
19
|
Defines the `Object` to which remote processes attach.
|
20
20
|
|
21
21
|
|
22
|
-
### [LanGrove::Handler::Base](https://github.com/cluetechnologies/langrove
|
22
|
+
### [LanGrove::Handler::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler)
|
23
23
|
|
24
24
|
Defines the `Object` that is spawned to handle each attached remote process.
|
25
25
|
|
26
26
|
|
27
|
-
### [LanGrove::Protocol::Base](https://github.com/cluetechnologies/langrove
|
27
|
+
### [LanGrove::Protocol::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol)
|
28
28
|
|
29
29
|
Defines the `Object` that encapsulates the method of communication.
|
30
30
|
|
31
31
|
|
32
|
-
### [LanGrove::Server::Base](https://github.com/cluetechnologies/langrove
|
32
|
+
### [LanGrove::Server::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server)
|
33
33
|
|
34
34
|
Defines the `Object` that houses the collection of all presently connected remote processes.
|
35
35
|
|
@@ -64,12 +64,12 @@ Secondary Components
|
|
64
64
|
====================
|
65
65
|
|
66
66
|
|
67
|
-
### [LanGrove::Behaviour::Base](https://github.com/cluetechnologies/langrove
|
67
|
+
### [LanGrove::Behaviour::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour)
|
68
68
|
|
69
69
|
Defines a set of Behaviours that can be applied to Primary Daemon Components
|
70
70
|
|
71
71
|
|
72
|
-
### [LanGrove::Plugin::Base](https://github.com/cluetechnologies/langrove
|
72
|
+
### [LanGrove::Plugin::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin)
|
73
73
|
|
74
74
|
Defines the `Interface Base` to implement Behaviour actions.
|
75
75
|
|
@@ -78,5 +78,5 @@ Defines the `Interface Base` to implement Behaviour actions.
|
|
78
78
|
Tools and Things
|
79
79
|
================
|
80
80
|
|
81
|
-
### [LanGrove::Ext](https://github.com/cluetechnologies/langrove
|
81
|
+
### [LanGrove::Ext](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/ext)
|
82
82
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
LanGrove::Adaptor::Base
|
6
6
|
========================
|
7
7
|
|
8
|
-
Defines the extendable `Interface` for spawning [Handler](https://github.com/cluetechnologies/langrove
|
8
|
+
Defines the extendable `Interface` for spawning [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler)s into the [Server](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server) process.
|
9
9
|
|
10
10
|
|
11
11
|
EventMachineAdaptor
|
@@ -15,20 +15,20 @@
|
|
15
15
|
LanGrove::Behaviour::Base
|
16
16
|
=========================
|
17
17
|
|
18
|
-
Defines the interface between the Daemon's [Primary Components](https://github.com/cluetechnologies/langrove
|
18
|
+
Defines the interface between the Daemon's [Primary Components](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove#primary-components) and the [Plugins](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin) that perform the Behaviour specified actions upon them.
|
19
19
|
|
20
20
|
Behaviour Triggers
|
21
21
|
------------------
|
22
22
|
|
23
23
|
Behaviours are assigned to action at configurable trigger points in each Daemon module's life cycle.
|
24
24
|
|
25
|
-
### [Server](https://github.com/cluetechnologies/langrove
|
25
|
+
### [Server](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server) Triggers
|
26
26
|
|
27
27
|
* :server_start
|
28
28
|
* :server_stop
|
29
29
|
* :server_reload
|
30
30
|
|
31
|
-
### [Handler](https://github.com/cluetechnologies/langrove
|
31
|
+
### [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler) Triggers
|
32
32
|
|
33
33
|
* :handler_start
|
34
34
|
* :handler_stop
|
@@ -42,11 +42,11 @@ Behaviours are assigned to action at configurable trigger points in each Daemon
|
|
42
42
|
* :handler_after_receive
|
43
43
|
* :handler_error
|
44
44
|
|
45
|
-
### [Adaptor](https://github.com/cluetechnologies/langrove
|
45
|
+
### [Adaptor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/adaptor) Triggers
|
46
46
|
|
47
47
|
* none
|
48
48
|
|
49
|
-
### [Protocol](https://github.com/cluetechnologies/langrove
|
49
|
+
### [Protocol](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol) Triggers
|
50
50
|
|
51
51
|
* none
|
52
52
|
|
@@ -54,17 +54,17 @@ Behaviours are assigned to action at configurable trigger points in each Daemon
|
|
54
54
|
Function
|
55
55
|
--------
|
56
56
|
|
57
|
-
* Behaviour triggers fire via the [Daemon Root](https://github.com/cluetechnologies/langrove
|
57
|
+
* Behaviour triggers fire via the [Daemon Root](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/root) module.
|
58
58
|
* The triggers are called by the Module undergoing the associated event.
|
59
59
|
* The call carries reference to the Module
|
60
|
-
* The listening behaviour passes the Module reference onward to the [Plugin](https://github.com/cluetechnologies/langrove
|
60
|
+
* The listening behaviour passes the Module reference onward to the [Plugin](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin) configured to perform the action.
|
61
61
|
|
62
62
|
|
63
63
|
Configuration
|
64
64
|
=============
|
65
65
|
|
66
66
|
* Behaviours are assigned to triggers in the :server: subconfig branch.
|
67
|
-
* Behaviours are assigned a [Plugin](https://github.com/cluetechnologies/langrove
|
67
|
+
* Behaviours are assigned a [Plugin](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin)
|
68
68
|
|
69
69
|
|
70
70
|
Behaviours
|
@@ -72,9 +72,9 @@ Behaviours
|
|
72
72
|
|
73
73
|
### Persistable
|
74
74
|
|
75
|
-
Requires a [Persistor](https://github.com/cluetechnologies/langrove
|
75
|
+
Requires a [Persistor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin#persistor) Plugin
|
76
76
|
|
77
|
-
Creates the ability to store and fetch the contents of the [Handler's Capsule](https://github.com/cluetechnologies/langrove
|
77
|
+
Creates the ability to store and fetch the contents of the [Handler's Capsule](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#the-capsule)
|
78
78
|
|
79
79
|
<pre>
|
80
80
|
|
@@ -103,11 +103,11 @@ Creates the ability to store and fetch the contents of the [Handler's Capsule](h
|
|
103
103
|
|
104
104
|
### Preloadable
|
105
105
|
|
106
|
-
Requires a [Persistor](https://github.com/cluetechnologies/langrove
|
106
|
+
Requires a [Persistor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin#persistor) Plugin
|
107
107
|
|
108
|
-
Currently only works with a [Multiplexing Socket Handler](https://github.com/cluetechnologies/langrove
|
108
|
+
Currently only works with a [Multiplexing Socket Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#socket-multiplexer)
|
109
109
|
|
110
|
-
Creates the ability to fetch all previously persisted [Handler Capsules](https://github.com/cluetechnologies/langrove
|
110
|
+
Creates the ability to fetch all previously persisted [Handler Capsules](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#the-capsule) ahead of goind to listen on the socket.
|
111
111
|
|
112
112
|
<pre>
|
113
113
|
|
@@ -157,9 +157,9 @@ Creates the ability to fetch all previously persisted [Handler Capsules](https:/
|
|
157
157
|
### Enqueueable
|
158
158
|
|
159
159
|
|
160
|
-
Requires an [Enqueuer](https://github.com/cluetechnologies/langrove
|
160
|
+
Requires an [Enqueuer](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin#enqueuer) Plugin
|
161
161
|
|
162
|
-
Enqueues a Job onto a specified Queue with the [Handler's Capsule](https://github.com/cluetechnologies/langrove
|
162
|
+
Enqueues a Job onto a specified Queue with the [Handler's Capsule](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#the-capsule) as payload.
|
163
163
|
|
164
164
|
|
165
165
|
|
@@ -16,6 +16,9 @@ module LanGrove
|
|
16
16
|
|
17
17
|
@@type = :daemon
|
18
18
|
|
19
|
+
attr_reader :server
|
20
|
+
attr_reader :adaptor
|
21
|
+
|
19
22
|
def connect
|
20
23
|
|
21
24
|
#
|
@@ -162,6 +165,11 @@ module LanGrove
|
|
162
165
|
def start
|
163
166
|
|
164
167
|
schedule_behaviours unless @server.nil?
|
168
|
+
|
169
|
+
#
|
170
|
+
# Start the introspector
|
171
|
+
#
|
172
|
+
@root.metrix.start( self )
|
165
173
|
|
166
174
|
#
|
167
175
|
# TODO: The client
|
@@ -179,7 +187,6 @@ module LanGrove
|
|
179
187
|
@config = config_hash
|
180
188
|
@daemon_name = daemon_name
|
181
189
|
|
182
|
-
|
183
190
|
#
|
184
191
|
# TODO: The client
|
185
192
|
#
|
@@ -8,6 +8,7 @@ module LanGrove
|
|
8
8
|
|
9
9
|
attr_accessor :logger
|
10
10
|
attr_accessor :config
|
11
|
+
attr_accessor :metrix
|
11
12
|
|
12
13
|
def initialize( config = {
|
13
14
|
|
@@ -22,6 +23,7 @@ module LanGrove
|
|
22
23
|
|
23
24
|
@logger = logger
|
24
25
|
@config = LanGrove::Config::Base.new( self, config, logger )
|
26
|
+
@metrix = LanGrove::Metrix::Base.new( self )
|
25
27
|
|
26
28
|
end
|
27
29
|
|
@@ -1,8 +1,234 @@
|
|
1
1
|
module LanGrove
|
2
|
+
|
3
|
+
module LogMonitor
|
4
|
+
|
5
|
+
module Sampler
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def init( root )
|
10
|
+
|
11
|
+
return if @initialized
|
12
|
+
|
13
|
+
@root = root
|
14
|
+
|
15
|
+
@root.logger.debug "#{self}.init( #{root} )"
|
16
|
+
|
17
|
+
@root.metrix.register_sampler(
|
18
|
+
|
19
|
+
:type => :handler,
|
20
|
+
:sampler => self,
|
21
|
+
:accumulator => proc { |component_type, component, state_doc|
|
22
|
+
|
23
|
+
#
|
24
|
+
# The component will only be sampled
|
25
|
+
# if it is a LogMonitor
|
26
|
+
#
|
27
|
+
|
28
|
+
self.sample_accumulate(
|
29
|
+
|
30
|
+
component_type, component, state_doc
|
31
|
+
|
32
|
+
) if component.respond_to?( :log_monitor_event )
|
33
|
+
|
34
|
+
}
|
35
|
+
|
36
|
+
)
|
37
|
+
|
38
|
+
@initialized = true
|
39
|
+
|
40
|
+
reset
|
41
|
+
|
42
|
+
return self
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def sample_accumulate( component_type, component, state_doc )
|
47
|
+
|
48
|
+
#@root.logger.debug "#{self}.sample_accumulate( #{component_type}, #{component}, #{state_doc} )"
|
49
|
+
|
50
|
+
@name = component.class.to_s.split(' ')[0]
|
51
|
+
|
52
|
+
@counters[:count] += 1
|
53
|
+
|
54
|
+
if component_type == :handler
|
55
|
+
|
56
|
+
if component.capsule['success']
|
57
|
+
|
58
|
+
@counters[:current_success] += 1
|
59
|
+
|
60
|
+
else
|
61
|
+
|
62
|
+
@counters[:current_fail] += 1
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
now = Time.now.to_i
|
67
|
+
|
68
|
+
if component.capsule['success_at']
|
69
|
+
|
70
|
+
@counters[:success_ever] += 1
|
71
|
+
|
72
|
+
at = component.capsule['success_at'].strftime( '%s' )
|
73
|
+
|
74
|
+
@counters[:success_age] << now - at.to_i
|
75
|
+
|
76
|
+
else
|
77
|
+
|
78
|
+
@counters[:success_never] += 1
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
if component.capsule['last_ran_at']
|
83
|
+
|
84
|
+
at = component.capsule['last_ran_at'].strftime( '%s' )
|
85
|
+
|
86
|
+
@counters[:last_run_age] << now - at.to_i
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
if component.capsule['known_errors']
|
91
|
+
|
92
|
+
component.capsule['known_errors'].each do |k,v|
|
93
|
+
|
94
|
+
if @counters[:known_errors][k].nil?
|
95
|
+
|
96
|
+
@counters[:known_errors][k] = 1
|
97
|
+
|
98
|
+
else
|
99
|
+
|
100
|
+
@counters[:known_errors][k] += 1
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
@counters[:known_errors_instance] += 1
|
105
|
+
@counters[:known_errors_total] += v
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
if component.capsule['unknown_errors']
|
112
|
+
|
113
|
+
component.capsule['unknown_errors'].each do |k,v|
|
114
|
+
|
115
|
+
if @counters[:unknown_errors][k].nil?
|
116
|
+
|
117
|
+
@counters[:unknown_errors][k] = 1
|
118
|
+
|
119
|
+
else
|
120
|
+
|
121
|
+
@counters[:unknown_errors][k] += 1
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
@counters[:unknown_errors_instance] += 1
|
126
|
+
@counters[:unknown_errors_total] += v
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
def sample_collate( component_type, state_doc )
|
137
|
+
|
138
|
+
#@root.logger.debug "#{self}.sample_collate( #{component_type}, #{state_doc} )"
|
139
|
+
|
140
|
+
success_age = 0.0
|
141
|
+
@counters[:success_age].each { |v| success_age += v }
|
142
|
+
|
143
|
+
last_run_age = 0.0
|
144
|
+
@counters[:last_run_age].each { |v| last_run_age += v }
|
145
|
+
|
146
|
+
state_doc[ @name ] = {
|
147
|
+
|
148
|
+
:count => @counters[:count],
|
149
|
+
|
150
|
+
:current_success => @counters[:current_success],
|
151
|
+
:current_fail => @counters[:current_fail],
|
152
|
+
|
153
|
+
:success_ever => @counters[:success_ever],
|
154
|
+
:success_never => @counters[:success_never],
|
155
|
+
|
156
|
+
:avg_success_age => success_age / @counters[:success_age].length,
|
157
|
+
:age_last_run_age => last_run_age / @counters[:last_run_age].length,
|
158
|
+
|
159
|
+
:known_errors_instance => @counters[:known_errors_instance],
|
160
|
+
:known_errors_total => @counters[:known_errors_total],
|
161
|
+
|
162
|
+
:unknown_errors_instance => @counters[:unknown_errors_instance],
|
163
|
+
:unknown_errors_total => @counters[:unknown_errors_total],
|
164
|
+
|
165
|
+
:known_errors => @counters[:known_errors],
|
166
|
+
:unknown_errors => @counters[:unknown_errors],
|
167
|
+
|
168
|
+
}
|
169
|
+
|
170
|
+
reset
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
def reset
|
175
|
+
|
176
|
+
#
|
177
|
+
# This may be quite nasty to the garbage collector...
|
178
|
+
#
|
179
|
+
|
180
|
+
@counters = {
|
181
|
+
|
182
|
+
:count => 0,
|
183
|
+
|
184
|
+
#
|
185
|
+
# current state
|
186
|
+
#
|
187
|
+
:current_success => 0,
|
188
|
+
:current_fail => 0,
|
189
|
+
|
190
|
+
#
|
191
|
+
# ever succeeded
|
192
|
+
#
|
193
|
+
:success_ever => 0,
|
194
|
+
:success_never => 0,
|
195
|
+
|
196
|
+
#
|
197
|
+
# age in seconds of each success
|
198
|
+
#
|
199
|
+
:success_age => [],
|
200
|
+
:last_run_age => [],
|
201
|
+
|
202
|
+
#
|
203
|
+
# known errors
|
204
|
+
#
|
205
|
+
:known_errors => {},
|
206
|
+
:known_errors_instance => 0,
|
207
|
+
:known_errors_total => 0, # includes repeat count
|
208
|
+
|
209
|
+
#
|
210
|
+
# unknown errors
|
211
|
+
#
|
212
|
+
:unknown_errors => {},
|
213
|
+
:unknown_errors_instance => 0,
|
214
|
+
:unknown_errors_total => 0
|
215
|
+
|
216
|
+
|
217
|
+
}
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
2
226
|
|
3
227
|
module LogMonitor
|
4
228
|
|
5
|
-
def log_monitor_config(
|
229
|
+
def log_monitor_config( root, hash )
|
230
|
+
|
231
|
+
@@sampler = Sampler.init( root )
|
6
232
|
|
7
233
|
#
|
8
234
|
# <hash> as the state storage (capsule)
|
@@ -11,9 +11,9 @@ Defines the `Object` that interacts with remote processes.
|
|
11
11
|
Function
|
12
12
|
--------
|
13
13
|
|
14
|
-
* A handler is spawned to handle each connection being made through the [Adaptor](https://github.com/cluetechnologies/langrove
|
14
|
+
* A handler is spawned to handle each connection being made through the [Adaptor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/adaptor).
|
15
15
|
* The handler remains connected to it's assigned remote process.
|
16
|
-
* Handlers are registered with the [Server](https://github.com/cluetechnologies/langrove
|
16
|
+
* Handlers are registered with the [Server](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server) collection.
|
17
17
|
* Handlers run idle in [EventMachine](http://eventmachine.rubyforge.org/EventMachine.html)'s event loop.
|
18
18
|
|
19
19
|
The Capsule
|
@@ -27,12 +27,12 @@ Event Callbacks
|
|
27
27
|
---------------
|
28
28
|
|
29
29
|
* The event loop fires callbacks into the Handler.
|
30
|
-
* Each callback also has associated [Behaviour](https://github.com/cluetechnologies/langrove
|
30
|
+
* Each callback also has associated [Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour) triggers.
|
31
31
|
|
32
32
|
|
33
33
|
### start()
|
34
34
|
|
35
|
-
This callback will fire into each connecting Handler after loading the [Protocol](https://github.com/cluetechnologies/langrove
|
35
|
+
This callback will fire into each connecting Handler after loading the [Protocol](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol) and Config.
|
36
36
|
|
37
37
|
|
38
38
|
### stop()
|
@@ -47,7 +47,7 @@ Informs each Handler that the Daemon received a sigHUP. The Config may have chan
|
|
47
47
|
|
48
48
|
### receive( decoded )
|
49
49
|
|
50
|
-
Data arrived at the socket and was decoded by the configured [Prococol](https://github.com/cluetechnologies/langrove
|
50
|
+
Data arrived at the socket and was decoded by the configured [Prococol](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol)
|
51
51
|
|
52
52
|
|
53
53
|
### TODO - connect()
|
@@ -24,8 +24,8 @@ Plugin Types
|
|
24
24
|
Persistor
|
25
25
|
---------
|
26
26
|
|
27
|
-
* Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove
|
28
|
-
* Supports the [Preloadable Behaviour](https://github.com/cluetechnologies/langrove
|
27
|
+
* Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#persistable)
|
28
|
+
* Supports the [Preloadable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#preloadable)
|
29
29
|
|
30
30
|
### `store( hander )`
|
31
31
|
|
@@ -35,7 +35,7 @@ Persistor
|
|
35
35
|
|
36
36
|
### Implementations
|
37
37
|
|
38
|
-
* [YamlFile](https://github.com/cluetechnologies/langrove
|
38
|
+
* [YamlFile](https://github.com/cluetechnologies/langrove/blob/master/lib/langrove/plugin/yaml_file.md)
|
39
39
|
* [langrove-plugin-mongodb.gem](https://github.com/cluetechnologies/langrove-plugin-mongodb)
|
40
40
|
|
41
41
|
|
@@ -46,7 +46,7 @@ Functionally identical to Persistor except it accumulates calls to store to enab
|
|
46
46
|
All updates are performed at the configured `:interval:`
|
47
47
|
|
48
48
|
* Only compatable with Eventmachine enabled daemons.
|
49
|
-
* Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove
|
49
|
+
* Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#persistable)
|
50
50
|
|
51
51
|
### Implementations
|
52
52
|
|
@@ -56,7 +56,7 @@ All updates are performed at the configured `:interval:`
|
|
56
56
|
Enqueuer
|
57
57
|
--------
|
58
58
|
|
59
|
-
* Supports the [Enqueueable Behaviour](https://github.com/cluetechnologies/langrove
|
59
|
+
* Supports the [Enqueueable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#enqueueable)
|
60
60
|
|
61
61
|
|
62
62
|
### `enqueue_key( handler )`
|
@@ -171,7 +171,7 @@ module LanGrove
|
|
171
171
|
# Use the pending capsule to assemble the
|
172
172
|
# persistance key.
|
173
173
|
#
|
174
|
-
data_hash = handler.pending_capsule
|
174
|
+
data_hash = handler.pending_capsule if handler.respond_to?( :pending_capsule )
|
175
175
|
|
176
176
|
#
|
177
177
|
# Fall back to using the actual capsule
|
@@ -17,13 +17,13 @@
|
|
17
17
|
LanGrove::Protocol::Base
|
18
18
|
========================
|
19
19
|
|
20
|
-
Defines the `Interface` that is employed to decode and encode data passing between the [Handler](https://github.com/cluetechnologies/langrove
|
20
|
+
Defines the `Interface` that is employed to decode and encode data passing between the [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler) and the remote process to which it is attached.
|
21
21
|
|
22
22
|
|
23
23
|
Function
|
24
24
|
--------
|
25
25
|
|
26
|
-
Each spawned [Handler](https://github.com/cluetechnologies/langrove
|
26
|
+
Each spawned [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler) is assigned an instance of the protocol and its configuration.
|
27
27
|
|
28
28
|
|
29
29
|
Configuration
|
data/lib/langrove/root/README.md
CHANGED
@@ -1,5 +1,38 @@
|
|
1
1
|
<pre>
|
2
2
|
|
3
|
+
#
|
4
|
+
# root |noun| ~ The force that through the green fuse drives the flower
|
5
|
+
# Drives my green age; that blasts the roots of trees
|
6
|
+
# Is my destroyer.
|
7
|
+
#
|
8
|
+
# And I am dumb to tell the crooked rose
|
9
|
+
# My youth is bent by the same wintry fever.
|
10
|
+
# The force that drives the water through the rocks
|
11
|
+
# Drives my red blood; that dries the mouthing streams
|
12
|
+
# Turns mine to wax.
|
13
|
+
#
|
14
|
+
# And I am dumb to mouth unto my veins
|
15
|
+
# How at the mountain spring the same mouth sucks.
|
16
|
+
# The hand that whirls the water in the pool
|
17
|
+
# Stirs the quicksand; that ropes the blowing wind
|
18
|
+
# Hauls my shroud sail.
|
19
|
+
#
|
20
|
+
# And I am dumb to tell the hanging man
|
21
|
+
# How of my clay is made the hangman’s lime.
|
22
|
+
# The lips of time leech to the fountain head;
|
23
|
+
# Love drips and gathers, but the fallen blood
|
24
|
+
# Shall calm her sores.
|
25
|
+
#
|
26
|
+
# And I am dumb to tell a weather’s wind
|
27
|
+
# How time has ticked a heaven round the stars.
|
28
|
+
#
|
29
|
+
# And I am dumb to tell the lover’s tomb
|
30
|
+
# How at my sheet goes the same crooked worm.
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# - Dylan Thomas (1914–1953)
|
34
|
+
#
|
35
|
+
|
3
36
|
</pre>
|
4
37
|
|
5
38
|
LanGrove::Root::Base
|
@@ -9,9 +42,15 @@ LanGrove::Root::Base
|
|
9
42
|
* Provides the `config` and `logger` to all daemon modules.
|
10
43
|
* Provides an event trigger interface into `Behaviour` and associated `Plugin` modules.
|
11
44
|
|
45
|
+
Metrix
|
46
|
+
------
|
47
|
+
|
48
|
+
pending...
|
49
|
+
|
50
|
+
|
51
|
+
|
12
52
|
Todo
|
13
53
|
----
|
14
54
|
|
15
|
-
* Provides an introspection interface into `Metrix` module.
|
16
55
|
* Provides a notification interface into `Alerter` module.
|
17
56
|
|
data/lib/langrove/root/base.rb
CHANGED
data/lib/langrove/root/config.rb
CHANGED
@@ -66,6 +66,41 @@ module LanGrove
|
|
66
66
|
|
67
67
|
end
|
68
68
|
|
69
|
+
def get_daemon_config( name, component = nil )
|
70
|
+
|
71
|
+
#
|
72
|
+
I.show "TODO: All config collection should pass through here"
|
73
|
+
#
|
74
|
+
|
75
|
+
@logger.debug "get_daemon_config( #{name}, #{component} )"
|
76
|
+
|
77
|
+
raise LanGrove::DaemonConfigException.new(
|
78
|
+
|
79
|
+
"No :daemons: named #{name}"
|
80
|
+
|
81
|
+
) if @config[:daemons][name].nil?
|
82
|
+
|
83
|
+
return @config[:daemons][name] if component == nil?
|
84
|
+
|
85
|
+
if @config[:daemons][name][component].nil?
|
86
|
+
|
87
|
+
@logger.error "No #{component} defined for :daemons: named #{name}"
|
88
|
+
return {}
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
return @config[:daemons][name][component]
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_daemon( name, component = nil, instance = true )
|
97
|
+
|
98
|
+
#
|
99
|
+
# Get instance[ ?.new ]
|
100
|
+
#
|
101
|
+
|
102
|
+
end
|
103
|
+
|
69
104
|
def get_plugin_config( name )
|
70
105
|
|
71
106
|
@config[:plugins][name]
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module LanGrove
|
4
|
+
|
5
|
+
module Metrix
|
6
|
+
|
7
|
+
class Base < LanGrove::Base
|
8
|
+
|
9
|
+
#
|
10
|
+
# Maintains a capsule 'image' of runtime state
|
11
|
+
#
|
12
|
+
attr_reader :capsule
|
13
|
+
|
14
|
+
#
|
15
|
+
# Persists the capsule
|
16
|
+
#
|
17
|
+
attr_accessor :key
|
18
|
+
attr_reader :persistor
|
19
|
+
|
20
|
+
def initialize( root )
|
21
|
+
|
22
|
+
super( root )
|
23
|
+
|
24
|
+
@config = root.config.get_daemon_config( DAEMON_NAME, :metrix )
|
25
|
+
|
26
|
+
I.show @config
|
27
|
+
|
28
|
+
@capsule = {
|
29
|
+
|
30
|
+
:id => "#{DAEMON_NAME}@#{Socket.gethostname}"
|
31
|
+
|
32
|
+
}
|
33
|
+
|
34
|
+
@persistor = nil
|
35
|
+
|
36
|
+
#
|
37
|
+
# register_sampler() informs this with sampler objects
|
38
|
+
# to process the daemon components
|
39
|
+
#
|
40
|
+
@samplers = {}
|
41
|
+
|
42
|
+
@interval = @config[:interval].nil? ? 60 * 5 : @config[:interval]
|
43
|
+
|
44
|
+
if @config[:persistor].nil?
|
45
|
+
|
46
|
+
#
|
47
|
+
# Defaults to persist runtime state 'image'
|
48
|
+
# to a yaml file at:
|
49
|
+
#
|
50
|
+
# daemon_root//log/daemon_name@hostname
|
51
|
+
#
|
52
|
+
|
53
|
+
@persistor = LanGrove::ClassLoader.create( {
|
54
|
+
|
55
|
+
:module => 'Plugin',
|
56
|
+
:class => 'YamlFile'
|
57
|
+
|
58
|
+
} ).new( root, {
|
59
|
+
|
60
|
+
:basedir => DAEMON_ROOT,
|
61
|
+
:database => '',
|
62
|
+
:table => 'log',
|
63
|
+
:key => {
|
64
|
+
:filename => :id
|
65
|
+
}
|
66
|
+
|
67
|
+
}, nil )
|
68
|
+
|
69
|
+
else
|
70
|
+
|
71
|
+
#
|
72
|
+
# But can use any configured persistor plugin
|
73
|
+
#
|
74
|
+
|
75
|
+
@persistor = root.config.get_plugin( @config[:persistor] )
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
raise config_exception(
|
80
|
+
|
81
|
+
"#{self.class} requires :persistor: to specify a configured persistor plugin."
|
82
|
+
|
83
|
+
) unless @persistor.is_a?( LanGrove::Plugin::Persistor )
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def register_sampler( spec )
|
88
|
+
|
89
|
+
type = :handler
|
90
|
+
filter = '*'
|
91
|
+
accumulator = nil
|
92
|
+
sampler = nil
|
93
|
+
|
94
|
+
spec.each do |key, value|
|
95
|
+
|
96
|
+
case key
|
97
|
+
|
98
|
+
when :type
|
99
|
+
|
100
|
+
type = value
|
101
|
+
|
102
|
+
when :sampler
|
103
|
+
|
104
|
+
sampler = value
|
105
|
+
|
106
|
+
when :filter
|
107
|
+
|
108
|
+
filter = value
|
109
|
+
|
110
|
+
when :accumulator
|
111
|
+
|
112
|
+
#
|
113
|
+
# Allows for an alternative accumulator callback
|
114
|
+
#
|
115
|
+
accumulator = value
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
@samplers[type] = {} if @samplers[type].nil?
|
122
|
+
@samplers[type][filter] = [] if @samplers[type][filter].nil?
|
123
|
+
@samplers[type][filter] << [accumulator, sampler]
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
def start( daemon )
|
128
|
+
|
129
|
+
@logger.debug "#{self.class}.start( #{daemon} )"
|
130
|
+
|
131
|
+
#
|
132
|
+
# Start the sample event loop
|
133
|
+
#
|
134
|
+
|
135
|
+
@daemon = daemon
|
136
|
+
|
137
|
+
if defined?( EM ) and EM::reactor_running?
|
138
|
+
|
139
|
+
EM::add_periodic_timer(@interval) do
|
140
|
+
|
141
|
+
sample
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
def sample
|
150
|
+
|
151
|
+
sample_handlers
|
152
|
+
|
153
|
+
sample_adaptors
|
154
|
+
|
155
|
+
I.show @capsule
|
156
|
+
|
157
|
+
@persistor.store( self )
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
def sample_handlers
|
162
|
+
|
163
|
+
@samplers[:handler]['*'].each do |sampler|
|
164
|
+
|
165
|
+
#
|
166
|
+
# sampler[0] contains the alternative accumulator callback proc
|
167
|
+
# sampler[1] contains the sampler object
|
168
|
+
#
|
169
|
+
|
170
|
+
@daemon.server.each_handler do |handler|
|
171
|
+
|
172
|
+
if sampler[0].nil?
|
173
|
+
|
174
|
+
sampler[1].sample_accumulate( :handler, handler, @capsule )
|
175
|
+
|
176
|
+
else
|
177
|
+
|
178
|
+
sampler[0].yield( :handler, handler, @capsule )
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
sampler[1].sample_collate( :handler, @capsule )
|
185
|
+
|
186
|
+
end unless @samplers[:handler].nil?
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
def sample_adaptors
|
191
|
+
|
192
|
+
@samplers[:adaptor]['*'].each do |sampler|
|
193
|
+
|
194
|
+
sampler[1].sample_accumulate( :adaptor, @daemon.adaptor, @capsule )
|
195
|
+
|
196
|
+
end unless @samplers[:adaptor].nil?
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
@@ -37,19 +37,6 @@ module LanGrove
|
|
37
37
|
|
38
38
|
end
|
39
39
|
|
40
|
-
module Metrix
|
41
|
-
|
42
|
-
class Base
|
43
|
-
|
44
|
-
#
|
45
|
-
# Collect internal runtime metrix from
|
46
|
-
# all local daemons
|
47
|
-
#
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
40
|
module Alerter
|
54
41
|
|
55
42
|
class Base
|
@@ -135,7 +122,8 @@ module LanGrove
|
|
135
122
|
|
136
123
|
config_instance
|
137
124
|
|
138
|
-
|
125
|
+
@config.instance_variable_set( :@logger, logger )
|
126
|
+
|
139
127
|
#
|
140
128
|
# Behaviours are configured to run at
|
141
129
|
# key points in the Daemon life cycle.
|
@@ -248,7 +236,7 @@ module LanGrove
|
|
248
236
|
# LAter...
|
249
237
|
#
|
250
238
|
@alerter = LanGrove::Alerter::Base.new
|
251
|
-
@metrix = LanGrove::Metrix::Base.new
|
239
|
+
@metrix = LanGrove::Metrix::Base.new( self )
|
252
240
|
|
253
241
|
end
|
254
242
|
|
data/lib/langrove/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'em-rspec'
|
3
|
+
|
4
|
+
describe LanGrove::Metrix::Base do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
|
8
|
+
CONFIG.flush
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
subject {
|
13
|
+
|
14
|
+
LanGrove::Metrix::Base.new( ROOT )
|
15
|
+
|
16
|
+
}
|
17
|
+
|
18
|
+
pending 'default to persisting runtime metrix as a yaml file' do
|
19
|
+
|
20
|
+
LOG.on
|
21
|
+
|
22
|
+
subject.persistor.should be_a( LanGrove::Plugin::YamlFile )
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
pending 'defaults to a 5 minute sample frequency' do
|
27
|
+
|
28
|
+
EM.should_receive( :add_periodic_timer ).with( 5 * 60 )
|
29
|
+
|
30
|
+
subject.start
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'allows registering functions as samplers' do
|
35
|
+
|
36
|
+
sampler1 = mock( 'A sampler for handlers' )
|
37
|
+
sampler2 = mock( 'A sampler for adaptors' )
|
38
|
+
|
39
|
+
CONFIG.create( 'daemon', :handler, 'Base' )
|
40
|
+
CONFIG.create( 'daemon', :adaptor, 'Base' )
|
41
|
+
CONFIG.create( 'daemon', :metrix, 'Base' )
|
42
|
+
|
43
|
+
@daemon, @server, @adaptor, @handler, @protocol =
|
44
|
+
LanGrove::SpecHelper::create_daemon_with_connected_handler( 'daemon', anything )
|
45
|
+
|
46
|
+
subject.instance_variable_set( :@daemon, @daemon )
|
47
|
+
|
48
|
+
sampler1.should_receive( :sample ).with( :handler, @handler, anything )
|
49
|
+
sampler2.should_receive( :sample ).with( :adaptor, @adaptor, anything )
|
50
|
+
|
51
|
+
subject.register_sampler( :type => :handler, :sampler => sampler1 )
|
52
|
+
subject.register_sampler( :type => :adaptor, :sampler => sampler2 )
|
53
|
+
|
54
|
+
subject.sample
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
pending 'can specify to sample only handlers of a specific type'
|
59
|
+
|
60
|
+
end
|
data/spec/spec_helper.rb
CHANGED
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.5.
|
4
|
+
version: 0.0.5.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-08-
|
15
|
+
date: 2012-08-09 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: eventmachine
|
@@ -117,8 +117,6 @@ executables:
|
|
117
117
|
extensions: []
|
118
118
|
extra_rdoc_files: []
|
119
119
|
files:
|
120
|
-
- .rspec
|
121
|
-
- .rvmrc
|
122
120
|
- Gemfile
|
123
121
|
- Gemfile.lock
|
124
122
|
- Guardfile
|
@@ -190,6 +188,7 @@ files:
|
|
190
188
|
- lib/langrove/root/README.md
|
191
189
|
- lib/langrove/root/base.rb
|
192
190
|
- lib/langrove/root/config.rb
|
191
|
+
- lib/langrove/root/metrix.rb
|
193
192
|
- lib/langrove/root/root_base.rb
|
194
193
|
- lib/langrove/server/README.md
|
195
194
|
- lib/langrove/server/base.rb
|
@@ -236,6 +235,7 @@ files:
|
|
236
235
|
- spec/langrove/protocol/protocol_base_spec.rb
|
237
236
|
- spec/langrove/protocol/syslog_spec.rb
|
238
237
|
- spec/langrove/root/config_spec.rb
|
238
|
+
- spec/langrove/root/metrix_spec.rb
|
239
239
|
- spec/langrove/root/root_base_spec.rb
|
240
240
|
- spec/langrove/server/server_base_spec.rb
|
241
241
|
- spec/spec_helper.rb
|
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|
data/.rvmrc
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
-
# development environment upon cd'ing into the directory
|
5
|
-
|
6
|
-
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
-
# Only full ruby name is supported here, for short names use:
|
8
|
-
# echo "rvm use 1.9.2" > .rvmrc
|
9
|
-
environment_id="ruby-1.9.2-p318@langrove"
|
10
|
-
|
11
|
-
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
-
# rvmrc_rvm_version="1.12.3 (master)" # 1.10.1 seams as a safe start
|
13
|
-
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
-
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
-
# return 1
|
16
|
-
# }
|
17
|
-
|
18
|
-
# First we attempt to load the desired environment directly from the environment
|
19
|
-
# file. This is very fast and efficient compared to running through the entire
|
20
|
-
# CLI and selector. If you want feedback on which environment was used then
|
21
|
-
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
-
then
|
25
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
-
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
-
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
-
if [[ $- == *i* ]] # check for interactive shells
|
29
|
-
then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
30
|
-
else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
|
31
|
-
fi
|
32
|
-
else
|
33
|
-
# If the environment file has not yet been created, use the RVM CLI to select.
|
34
|
-
rvm --create use "$environment_id" || {
|
35
|
-
echo "Failed to create RVM environment '${environment_id}'."
|
36
|
-
return 1
|
37
|
-
}
|
38
|
-
fi
|
39
|
-
|
40
|
-
|
41
|
-
# If you use bundler, this might be useful to you:
|
42
|
-
# if [[ -s Gemfile ]] && {
|
43
|
-
# ! builtin command -v bundle >/dev/null ||
|
44
|
-
# builtin command -v bundle | grep $rvm_path/bin/bundle >/dev/null
|
45
|
-
# }
|
46
|
-
# then
|
47
|
-
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
48
|
-
# gem install bundler
|
49
|
-
# fi
|
50
|
-
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
|
51
|
-
# then
|
52
|
-
# bundle install | grep -vE '^Using|Your bundle is complete'
|
53
|
-
# fi
|