carioca 1.0 → 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5725ebfdae23b3175784bfc8f961a8ee5d31c455
4
+ data.tar.gz: 564985d9a48ab2e72017dca0b08d0c556ae0627b
5
+ SHA512:
6
+ metadata.gz: 7690724ad858c0f2a29f48bde4b7dd1674afdc9ed9a3cb0a5adfecb00b55e0338a33ddee6842829783140684f3e3bd2f014eabee48ab07c45f0468ce1d33207d
7
+ data.tar.gz: 6a3ab862d8c13fab2ddb0ac9fb7de1fd3ef4d6ce47e83750254e242dc36de6a68eaee9efe720840421744d39540f4c5b7f964b6895983c50b5dc14303bf43b6e
data/Gemfile CHANGED
@@ -1,11 +1,4 @@
1
1
  source "http://rubygems.org"
2
- gem "yard-rspec"
3
- gem "rspec", :require => "spec"
4
- gem "rake"
5
- gem "yard"
6
- gem "rdoc"
7
- gem "rcov"
8
- gem "roodi"
9
- gem "uuid"
10
- gem "methodic"
11
- gem "code_statistics"
2
+
3
+ gemspec
4
+
@@ -1,31 +1,29 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- code_statistics (0.2.13)
5
- diff-lcs (1.1.3)
6
- json (1.6.5)
7
- macaddr (1.0.0)
8
- methodic (0.2)
9
- rake (0.9.2.2)
10
- rcov (1.0.0)
11
- rdoc (3.12)
12
- json (~> 1.4)
4
+ diff-lcs (1.2.1)
5
+ macaddr (1.6.1)
6
+ systemu (~> 2.5.0)
7
+ methodic (1.2)
8
+ rake (10.0.4)
9
+ rdoc (4.0.0)
13
10
  roodi (2.2.0)
14
11
  ruby_parser (~> 2.3.0)
15
- rspec (2.9.0)
16
- rspec-core (~> 2.9.0)
17
- rspec-expectations (~> 2.9.0)
18
- rspec-mocks (~> 2.9.0)
19
- rspec-core (2.9.0)
20
- rspec-expectations (2.9.0)
21
- diff-lcs (~> 1.1.3)
22
- rspec-mocks (2.9.0)
12
+ rspec (2.13.0)
13
+ rspec-core (~> 2.13.0)
14
+ rspec-expectations (~> 2.13.0)
15
+ rspec-mocks (~> 2.13.0)
16
+ rspec-core (2.13.1)
17
+ rspec-expectations (2.13.0)
18
+ diff-lcs (>= 1.1.3, < 2.0)
19
+ rspec-mocks (2.13.0)
23
20
  ruby_parser (2.3.1)
24
21
  sexp_processor (~> 3.0)
25
22
  sexp_processor (3.2.0)
26
- uuid (2.3.1)
23
+ systemu (2.5.2)
24
+ uuid (2.3.7)
27
25
  macaddr (~> 1.0)
28
- yard (0.7.5)
26
+ yard (0.8.5.2)
29
27
  yard-rspec (0.1)
30
28
  yard
31
29
 
@@ -33,10 +31,8 @@ PLATFORMS
33
31
  ruby
34
32
 
35
33
  DEPENDENCIES
36
- code_statistics
37
34
  methodic
38
35
  rake
39
- rcov
40
36
  rdoc
41
37
  roodi
42
38
  rspec
data/README.md CHANGED
@@ -14,6 +14,9 @@ Carioca provide :
14
14
  - a complete Configuration Agent
15
15
  - A service Registry (base on IOC/DI pattern)
16
16
 
17
+ [![Build Status](https://travis-ci.org/lecid/carioca.png?branch=master)](https://travis-ci.org/lecid/carioca)
18
+
19
+
17
20
  ## Installation
18
21
 
19
22
  In a valid Ruby environment :
data/Rakefile CHANGED
@@ -5,7 +5,6 @@ require 'rake'
5
5
  require "rake/clean"
6
6
  require "rubygems/package_task"
7
7
  require "rdoc/task"
8
- require 'code_statistics'
9
8
  require 'rspec/core/rake_task'
10
9
  require 'yard'
11
10
  require 'yard/rake/yardoc_task.rb'
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{carioca}
3
3
  s.author = "Romain GEORGES"
4
- s.version = "1.0"
4
+ s.version = "1.1"
5
5
  s.date = %q{2013-02-18}
6
6
  s.summary = %q{Carioca : Configuration Agent and Registry with Inversion Of Control for your Applications}
7
7
  s.email = %q{romain@ultragreen.net}
@@ -9,8 +9,15 @@ Gem::Specification.new do |s|
9
9
  s.description = %q{Carioca : provide a full IoC light Container for designing your applications}
10
10
  s.has_rdoc = true
11
11
  s.files = Dir['*/*/*/*'] + Dir['*/*/*'] + Dir['*/*'] + Dir['*']
12
- s.bindir = nil
13
- s.add_dependency('methodic', '>= 1.2')
12
+ s.add_development_dependency('rspec')
13
+ s.add_development_dependency('yard')
14
+ s.add_development_dependency('rdoc')
15
+ s.add_development_dependency('roodi')
16
+ s.add_development_dependency('uuid')
17
+ s.add_development_dependency('code_statistics')
18
+ s.add_development_dependency('yard-rspec')
19
+ s.add_dependency('dorsal')
20
+ s.add_dependency('methodic')
14
21
  s.required_ruby_version = '>= 1.8.1'
15
22
  s.rdoc_options << '--title' << 'Carioca : Gem documentation' << '--main' << 'doc/manual.rdoc' << '--line-numbers'
16
23
  # << '--diagram'
@@ -1,4 +1,6 @@
1
+
1
2
  #!/usr/bin/env ruby
3
+ # -*- coding: utf-8 -*-
2
4
  #---
3
5
  # Author : Romain GEORGES
4
6
  # type : gem component library
@@ -8,9 +10,8 @@
8
10
  require 'yaml'
9
11
  require 'rubygems'
10
12
  require 'methodic'
11
- require 'services'
12
- require 'daemons'
13
- require 'carioca_private'
13
+ require 'carioca/services'
14
+ require 'carioca/private'
14
15
 
15
16
 
16
17
 
@@ -48,7 +49,10 @@ module Carioca
48
49
  private :require_service
49
50
  private :instanciate_service
50
51
  private :kill_service
51
-
52
+ private :scan_instance_suffix
53
+ private :kill_distributed_service
54
+ private :shutdown_ring_if_empty
55
+
52
56
 
53
57
  @@inst = nil
54
58
 
@@ -62,10 +66,9 @@ module Carioca
62
66
  # registry = Carioca::Services::Registry.init :file => 'myservices.registry' # or
63
67
  # registry = Carioca::Services::Registry.init :file => 'myservices.registry', :debug => true
64
68
  def Registry.init(_options = {})
65
- options = Methodic::get_options(_options) do |m|
66
- m.specify_defaults_value :file => './services.registry', :debug => false
67
- m.merge!
68
- end
69
+ options = Methodic::get_options(_options)
70
+ options.specify_defaults_values :file => './services.registry', :debug => false, :name => 'Carioca'
71
+ options.merge
69
72
  @@inst = new(options) if @@inst.nil?
70
73
  return @@inst
71
74
  end
@@ -98,6 +101,14 @@ module Carioca
98
101
  # p registry.debug
99
102
  # @attr_reader [TrueClass,FalseClass] debug a boolean of the current debug status
100
103
  attr_reader :debug
104
+
105
+ # @example
106
+ # registry = Carioca::Services::Registry.init
107
+ # p registry.name
108
+ # registry.name = 'Agent'
109
+ # @attr_reader [String] the name of the Registry, used for distributed services
110
+ # @note default value is 'Carioca'
111
+ attr_accessor :name
101
112
 
102
113
  # writer accessor for debug (interaction with log service)
103
114
  # @example
@@ -129,22 +140,18 @@ module Carioca
129
140
  options.specify_class_of :name => String
130
141
  options.specify_presence_of([:name])
131
142
  options.validate!
132
- if @loaded_services.include?(options[:name]) then
133
- # prevent logger services killing
134
- if options[:name] == 'logger' then
135
- @log.debug('Carioca') { "Service logger can't be unloaded" } if @log
136
- return false
137
- end
138
- # calling private killer
139
- kill_service options[:name]
140
- @log.debug('Carioca') { "Service #{options[:name]} stopped" } if @log
141
- return true
143
+ @log.debug('Carioca') { "Service logger can't be unloaded" } if @log and options[:name] == 'logger'
144
+ return false if options[:name] == 'logger'
145
+ if @loaded_services.include?(options[:name]) then
146
+ options = scan_instance_suffix(options)
147
+ return kill_distributed_service options if @list[options[:shortname]][:distributed]
148
+ return kill_service options
142
149
  else
143
150
  @log.debug('Carioca') { "Service #{options[:name]} not loaded" } if @log
144
- return false
151
+ return false
145
152
  end
146
-
147
153
  end
154
+
148
155
 
149
156
  # register a new service in registry added to @list
150
157
  # @param [Hash] _options the options hash, key are :symbols
@@ -155,17 +162,14 @@ module Carioca
155
162
  # @option _options [String] :description the description of the service (required)
156
163
  # @option _options [Hash] :init_options the params of the service, keys are symbols
157
164
  # @option _options [Array] :requires the list of [String] services name required to load this service
165
+ # @option _options [TruClass|FalseClass] :distributed if service must be load as a distributed service
158
166
  # @return [TrueClass,FalseClass] true if service is added
159
167
  # @raise ArgumentError when :type is not in [:gem,:file,:builtin]
160
168
  def register_service(_options)
161
169
  options = Methodic.get_options(_options)
162
170
  options.specify_classes_of({:name => String, :resource => String, :description => String, :type => Symbol, :service => String })
163
171
  options.specify_presences_of([:name,:type,:resource,:service])
164
- cond = Proc::new{|option| case option
165
- when :gem then true
166
- when :file then true
167
- when :builtin then true
168
- else false end }
172
+ cond = Proc::new{|option| if [:gem,:gem_file,:file,:builtin].include? option then true else false end }
169
173
  options.specify_condition_for :type => cond
170
174
  options.validate!
171
175
  _name = _options.delete(:name)
@@ -253,16 +257,15 @@ module Carioca
253
257
  options.specify_classes_of :name => String
254
258
  options.specify_presences_of [:name]
255
259
  options.validate!
256
-
257
- if @loaded_services.include? options[:name] then
260
+ options = scan_instance_suffix(options)
261
+ dist = (@list[options[:shortname]][:distributed].nil?)? false : @list[options[:shortname]][:distributed]
262
+ if dist and @loaded_services.include? options[:name] then
263
+ @log.debug('Carioca') { "Restarting distributed service #{options[:name]}"} if @log
264
+ kill_distributed_service options
265
+ elsif @loaded_services.include? options[:name] then
258
266
  @log.debug('Carioca') { "Restarting service #{options[:name]}"} if @log
259
- kill_service :name => options[:name]
267
+ kill_service options
260
268
  end
261
- if options[:name] =~ /.*_.*/ then
262
- (options[:shortname],options[:instance]) = options[:name].split(/_/)
263
- else
264
- options[:shortname] = options[:name]
265
- end
266
269
  verify_requires_dependancies(options)
267
270
  require_service(options)
268
271
  return instanciate_service(options)
@@ -276,13 +279,16 @@ module Carioca
276
279
  # @return [TrueClass,FalseClass] true if registry closed successfully
277
280
  def close
278
281
  @log.debug('Carioca') { "closing Registry ..." }
282
+ options = Hash::new
279
283
  @loaded_services.keys.each do |service|
280
- next if service == 'logger'
281
- @log.debug('Carioca') { "Stopping service #{service} ..."}
282
- self.stop_service :name => service
284
+ options[:name] = service
285
+ options = scan_instance_suffix(options)
286
+ next if options[:name] == 'logger'
287
+ kill_distributed_service :name => options[:name], :preserve => true if @list[options[:shortname]][:distributed]
288
+ kill_service options unless @list[options[:shortname]][:distributed]
283
289
  end
284
290
  @log.debug('Carioca') { "Registry services closed, logger will be closed asynchronously" }
285
- kill_service 'logger'
291
+ kill_service :name => 'logger'
286
292
  return true
287
293
  end
288
294
 
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ #---
3
+ # Author : Romain GEORGES
4
+ # type : gem component library
5
+ # obj : Carioca Exceptions definition Module
6
+ #---
7
+
8
+ # Exception overload class for Carioca
9
+ class RegistryError < Exception; end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ #---
3
+ # Author : Romain GEORGES
4
+ # type : gem component library
5
+ # obj : Carioca Helpers definition Module
6
+ #---
7
+
8
+ class Class
9
+ # Usage:
10
+ # prelaod_service :name => 'service', :params => { :arg => 'value'}
11
+ def preload_service(_options = {})
12
+ Carioca::Services::Registry.init.start_service _options
13
+ end
14
+
15
+ def use_configuration(_options = {})
16
+ options = Methodic.get_options(_options)
17
+ options.specify_classes_of :with_file => String
18
+ options.specify_default_value_of :with_file => 'services/registry.yml'
19
+ options.merge
20
+ options.validate!
21
+ Carioca::Services::Registry.init.start_service :name => 'configuration', :params => { :config_file => options[:with_file]}
22
+ end
23
+ end
24
+
25
+
26
+ Module.class_eval do
27
+ def init_registry _options={}
28
+ options = Methodic.get_options(_options)
29
+ options.specify_classes_of :with_file => String
30
+ options.specify_default_value_of :with_file => 'services/registry.yml'
31
+ options.merge
32
+ options.validate!
33
+ Carioca::Services::Registry.init :file => options[:with_file]
34
+ end
35
+ end
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env ruby
2
+ #---
3
+ # Author : Romain GEORGES
4
+ # type : gem component library
5
+ # obj : Carioca Private Module (mixin for Carioca::Services::Registry)
6
+ #---
7
+
8
+ # private methods to mixin Carioca::Services::Registry
9
+ # @private
10
+ module PrivateMethodsCariocaServicesRegistry
11
+
12
+
13
+ # private initializer
14
+ def initialize(_options)
15
+ @logger_not_in_reg = false
16
+ @debug = _options[:debug]
17
+ @registry_filename = _options[:file]
18
+ @name = _options[:name]
19
+ @list = Hash::new
20
+ load if File::exist?(@registry_filename)
21
+ unless @list.include?('logger') then
22
+ self.register_service({:name => 'logger',
23
+ :service => 'Carioca::Services::InternalLogger',
24
+ :resource => 'logger',
25
+ :description => "The standard ruby Logger internal wrapper Service",
26
+ :type => :builtin,
27
+ :init_options => { :target => "/tmp/log.file"}})
28
+ @logger_not_in_reg = true
29
+ end
30
+ @loaded_services = Hash::new
31
+ # preload logger service
32
+ @log = self.start_service :name => 'logger'
33
+ @log.level =(@debug)? Logger::DEBUG : Logger::INFO
34
+ @log.debug('Carioca') { "Registry started, service logger preloaded" }
35
+ @log.debug('Carioca') { "Logger registered, not in configured registry" } if @logger_not_in_reg
36
+ end
37
+
38
+ # verify dependancies in services structure
39
+ # in @list from a service defition
40
+ # in _options and start it if needed
41
+ def verify_requires_dependancies(_options)
42
+ _name = _options[:shortname]
43
+ if @list[_name].include?(:requires) then
44
+ @list[_name][:requires].each do |service|
45
+ raise RegistryError::new 'Missing Required depedancy #{service}' unless @list.keys.include? service
46
+ unless @loaded_services.include?(service) then
47
+ @log.debug('Carioca') { "Registry dependancy found and not loaded : #{service}" }
48
+ restart_service :name => service
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ # require file for a service
55
+ # from a service definition in _options
56
+ def require_service(_options)
57
+ _name = _options[:shortname]
58
+ sym = ":#{@list[_name][:service].split('::').last}"
59
+ case @list[_name][:type]
60
+ when :file then
61
+ require @list[_name][:resource]
62
+ when :builtin then
63
+ _file = Carioca::Services::search_builtins _name
64
+ if _file then
65
+ require _file
66
+ else
67
+ raise RegistryError::new("Config failed")
68
+ end
69
+ when :gem then
70
+ require @list[_name][:resource]
71
+ when :gem_file then
72
+ (_name,_file) = @list[_name][:resource].split(':')
73
+ _dfile = Carioca::Services::search_file_in_gem _name,_file
74
+ if _dfile then
75
+ require _dfile
76
+ else
77
+ raise RegistryError::new("Config failed")
78
+ end
79
+ else
80
+ raise RegistryError::new("Config failed")
81
+ end
82
+ end
83
+
84
+
85
+ # scan for <service>_<instance> and rewrite options with :name and :shortname, :instance
86
+ def scan_instance_suffix(options)
87
+ if options[:name] =~ /.*_.*/ then
88
+ (options[:shortname],options[:instance]) = options[:name].split(/_/)
89
+ else
90
+ options[:shortname] = options[:name]
91
+ end
92
+ return options
93
+ end
94
+
95
+ #shutdown ring server if empty
96
+ def shutdown_ring_if_empty
97
+ get_ring if @ring_server.nil?
98
+ if @ring_server.list_services.empty? then
99
+ @log.debug('Carioca') { "Stopping Ultragreen Ring server if no distributed services found" }
100
+ @dorsal_controller.stop_ring_server
101
+ end
102
+ end
103
+
104
+ # run a ring servier instance or get existing
105
+ def get_ring
106
+ @dorsal_controller = start_service :name => 'dorsal'
107
+ @ring_server = @dorsal_controller.bind_to_ring
108
+ if @ring_server.nil? then
109
+ @dorsal_controller.start_ring_server
110
+ @ring_server = @dorsal_controller.bind_to_ring
111
+ @log.debug('Carioca') { "Starting new Ring Server" } if @log
112
+ else
113
+ @log.debug('Carioca') { "Getting already started Ring Server" } if @log
114
+ end
115
+ end
116
+
117
+ # instanciate Object from class defintion of a service defined in
118
+ # the service definition in _opts
119
+ def instanciate_service(_opts)
120
+ _name = _opts[:shortname]
121
+ dist = (@list[_name][:distributed].nil?)? false : @list[_name][:distributed]
122
+ get_ring if dist
123
+ @list[_name][:init_options].merge! _opts[:params] unless _opts[:params].nil?
124
+ @obj = Object::new
125
+ if @list[_name][:init_options].nil? then
126
+ eval("@obj = #{@list[_name][:service]}::new")
127
+ else
128
+ eval("@obj = #{@list[_name][:service]}::new(@list[_name][:init_options])")
129
+ end
130
+ if dist then
131
+ @ring_server.start_service({ :name => _opts[:name], :object => @obj, :description => @list[_name][:description], :owner => @name })
132
+ @loaded_services[_opts[:name]] = @ring_server.bind_to_service :name => _opts[:name]
133
+ else
134
+ @loaded_services[_opts[:name]] = @obj
135
+ end
136
+ return @loaded_services[_opts[:name]]
137
+ end
138
+
139
+ # call the garbage method of a service if exist and
140
+ # Delete from the loaded services list
141
+ def kill_service(options)
142
+ @log.debug('Carioca') { "Service #{options[:name]} stopped" } if @log
143
+ @loaded_services[options[:name]].garbage if @loaded_services[options[:name]].respond_to? :garbage
144
+ @loaded_services.delete(options[:name])
145
+ return true
146
+ end
147
+
148
+ def kill_distributed_service(options)
149
+ preserve = (options[:preserve].nil?)? false : options[:preserve]
150
+ get_ring if @ring_server.nil?
151
+ if @ring_server.list_services.include?(options[:name]) then
152
+ if options[:preserve] and @ring_server.list_services[options[:name]][:owner] != @name then
153
+ @log.debug('Carioca') { "Unlinking distributed Service #{options[:name]} owned by #{@name}." } if @log
154
+ else
155
+ @ring_server.destroy_service :name => options[:name]
156
+ @log.debug('Carioca') { "Killing distributed Service #{options[:name]}." } if @log
157
+ end
158
+ @loaded_services.delete(options[:name])
159
+ shutdown_ring_if_empty
160
+ return true
161
+ else
162
+ @log.debug('Carioca') { "Distributed service #{options[:name]} not in ring" } if @log
163
+ return false
164
+ end
165
+ end
166
+
167
+
168
+ end # end of PrivateMethodsCariocaServicesRegistry
169
+
170
+