carioca 1.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +18 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +3 -0
  5. data/Gemfile +6 -1
  6. data/Gemfile.lock +42 -34
  7. data/README.md +12 -220
  8. data/Rakefile +5 -59
  9. data/bin/console +15 -0
  10. data/bin/setup +8 -0
  11. data/carioca.gemspec +41 -25
  12. data/config/locales/en.yml +15 -0
  13. data/config/locales/fr.yml +19 -0
  14. data/lib/carioca/configuration.rb +47 -0
  15. data/lib/carioca/constants.rb +45 -0
  16. data/lib/carioca/container.rb +16 -0
  17. data/lib/carioca/dependencies.rb +19 -0
  18. data/lib/carioca/helpers.rb +44 -31
  19. data/lib/carioca/mixin.rb +32 -0
  20. data/lib/carioca/{tasks/rake.rb → rake/manage.rb} +4 -6
  21. data/lib/carioca/rake/tasks/registry.tasks +57 -0
  22. data/lib/carioca/registry.rb +93 -0
  23. data/lib/carioca/registry_file.rb +62 -0
  24. data/lib/carioca/services/config.rb +140 -0
  25. data/lib/carioca/services/i18n.rb +20 -0
  26. data/lib/carioca/services/init.rb +2 -0
  27. data/lib/carioca/validator.rb +49 -0
  28. data/lib/carioca.rb +2 -319
  29. data/samples/Rakefile +2 -0
  30. data/samples/config/carioca.registry +22 -0
  31. data/samples/config/locales/en.yml +2 -0
  32. data/samples/config/locales/es.yml +2 -0
  33. data/samples/config/locales/fr.yml +2 -0
  34. data/samples/config/settings.yml +24 -0
  35. data/samples/test.rb +71 -0
  36. metadata +59 -152
  37. data/AUTHORS +0 -8
  38. data/COPYRIGHT +0 -24
  39. data/ChangeLog +0 -7
  40. data/INSTALL +0 -7
  41. data/doc/manual.rdoc +0 -225
  42. data/lib/carioca/exceptions.rb +0 -9
  43. data/lib/carioca/private.rb +0 -170
  44. data/lib/carioca/services/configuration.rb +0 -187
  45. data/lib/carioca/services/debug.rb +0 -73
  46. data/lib/carioca/services/logger.rb +0 -58
  47. data/lib/carioca/services.rb +0 -143
  48. data/lib/carioca/tasks/registry_init.rake +0 -11
  49. data/spec/carioca_spec.rb +0 -459
  50. data/spec/config/services.registry +0 -55
  51. data/spec/init_spec.rb +0 -1
  52. data/spec/samples/dummy.rb +0 -10
  53. data/spec/samples/otherdummy.rb +0 -10
  54. data/spec/samples/requireddummy.rb +0 -10
  55. data/spec/spec_helper.rb +0 -11
  56. data/test.rb +0 -12
  57. data/ultragreen_roodi_coding_convention.yml +0 -25
@@ -1,170 +0,0 @@
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
-
@@ -1,187 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # $BUILTIN
3
- # $NAME configuration
4
- # $SERVICE Carioca::Services::Configuration
5
- # $RESOURCE configuration
6
- # $DESCRIPTION The Carioca Configuration Service
7
- # $INIT_OPTIONS config_file => ./.config
8
-
9
- # Copyright Ultragreen (c) 2005
10
- #---
11
- # Author : Romain GEORGES
12
- # type : class definition Ruby
13
- # obj : Generic config library
14
- #---
15
- # $Id$
16
-
17
-
18
- require 'rubygems'
19
- require 'methodic'
20
- require 'carioca/services'
21
- require 'yaml'
22
- require 'drb/drb'
23
-
24
- # overwriting Hash class
25
- # @private
26
- class Hash
27
-
28
- # recursively transform Hash keys form String to Symbols
29
- # come from Rails code
30
- # exist in Ruby 2.0
31
- def deep_symbolize
32
- target = dup
33
- target.inject({}) do |memo, (key, value)|
34
- value = value.deep_symbolize if value.is_a?(Hash)
35
- memo[key.to_sym] = value
36
- memo
37
- end
38
- end
39
-
40
- # pretty accessor for hash record
41
- # like ahash[:key] => ahash.key
42
- # r/w accessor
43
- def method_missing(name, *args, &block)
44
- if name.to_s =~ /(.+)=$/
45
- self[$1.to_sym] = args.first
46
- else
47
- self[name.to_sym]
48
- end
49
- end
50
- end
51
-
52
-
53
-
54
-
55
-
56
- module Carioca
57
-
58
- module Services
59
-
60
- # settings Hash record utilities class
61
- # @note please do not use Standalone ( dependancy of Configuration class )
62
- # @private
63
- class Settings < Hash
64
-
65
-
66
- # the name of the config file in YAML format
67
- attr_accessor :config_file
68
-
69
- # constructor (pre-open the config file in YAML)
70
- # @param [Hash] options the options records
71
- # @option options [String] :config_file (REQUIRED) the name of the config file
72
- # @option options [String] :context a context (root) name to bind in YAML Structure
73
- def initialize(options = {})
74
- @config_file = options[:config_file]
75
- newsets = {}
76
- if File::exist?(@config_file) then
77
- newsets = YAML::load_file(@config_file).deep_symbolize
78
- newsets = newsets[options[:context].to_sym] if options[:context] && newsets[options[:context].to_sym]
79
- deep_merge!(self, newsets)
80
- end
81
- end
82
-
83
- # save the Hash(self) in the file named by @config_file
84
- # @return [TrueClass,FalseClass] true if save! successfull
85
- def save!
86
- res = false
87
- File.open(@config_file, "w") do |f|
88
- res = true if f.write(self.to_yaml)
89
- end
90
- return res
91
- end
92
-
93
-
94
- private
95
- # full recursive merger for hash
96
- def deep_merge!(target, data)
97
- merger = proc{|key, v1, v2|
98
- Settings === v1 && Settings === v2 ? v1.merge(v2, &merger) : v2 }
99
- target.merge! data, &merger
100
- end
101
-
102
-
103
- end
104
-
105
-
106
-
107
-
108
- # Service Configuration of Carioca
109
- class Configuration
110
-
111
- include DRb::DRbUndumped
112
-
113
- # @example
114
- # config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
115
- # p config.config_file
116
- # config_file = 'newfilename'
117
- # @attr_reader [String] the filename of the YAML struct
118
- attr_accessor :settings
119
-
120
-
121
- # Configuration service constructor (open config)
122
- # @param [Hash] _options the params
123
- # @option _options [String] :config_file the filename of the config
124
- def initialize(_opts = {})
125
-
126
-
127
- options = Methodic.get_options(_opts)
128
- options.specify_default_value :config_file => "./.config"
129
- options.merge
130
- @settings = Carioca::Services::Settings.new(options)
131
- end
132
-
133
- # Proxy to @settings.save!
134
- # save the Hash(self) in the file named by @config_file
135
- # @return [TrueClass,FalseClass] true if save! successfull
136
- # @example usage
137
- # config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
138
- # config.config_file = 'newfile'
139
- # config.save!
140
- def save!
141
- @settings.save!
142
- end
143
-
144
-
145
- # reading wrapper to @settings.config_file accessor
146
- # @return [String] @config_file the file name
147
- # @example usage
148
- # config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
149
- # p config.config_file
150
- def config_file
151
- @settings.config_file
152
- end
153
-
154
- # writting wrapper to @settings.config_file accessor
155
- # @param [String] name the file name
156
- # @example usage
157
- # config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
158
- # config.config_file = 'newfile'
159
- def config_file=(name)
160
- @settings.config_file = name
161
- end
162
-
163
-
164
- # garbage service hook
165
- # @note close the logger
166
- # @note call by Carioca::Services::Registry#close
167
- def garbage
168
- @settings = nil
169
- return true
170
- end
171
-
172
- end
173
- end
174
- end
175
-
176
-
177
-
178
-
179
-
180
- # interactive hacks
181
- if $0 == __FILE__ then
182
- conf =Carioca::Services::Configuration::new :config_file => 'spec/config/.config'
183
- p conf
184
- puts "#{File::basename(__FILE__)}:"
185
- puts 'this is a RUBY library file'
186
- puts "Copyright (c) Ultragreen"
187
- end
@@ -1,73 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # $BUILTIN
3
- # $NAME debug
4
- # $SERVICE Carioca::Services::ProxyDebug
5
- # $RESOURCE debug
6
- # $DESCRIPTION Proxy class debugger Service for Carioca
7
- # Copyright Ultragreen (c) 2012
8
- #---
9
- # Author : Romain GEORGES
10
- # type : class definition Ruby
11
- # obj : Generic Debugs tools library
12
- #---
13
-
14
-
15
- require 'rubygems'
16
- require 'methodic'
17
-
18
-
19
- module Carioca
20
- module Services
21
-
22
-
23
- # Service Debug of Carioca
24
- # Proxy Class Debug for devs
25
- class ProxyDebug
26
-
27
- # ProxyDebug service constructor (has a class proxy => so a service proxy)
28
- # @param [Hash] _options the params
29
- # @option _options [String] :service the name of the service you want to proxyfying
30
- # @option _options [Hash] :params the params of the proxyfied service
31
- def initialize(_options)
32
- options = Methodic.get_options(_options)
33
- options.specify_classes_of :service => String
34
- options.specify_presence_of([:service])
35
- options.validate!
36
- if options[:params] then
37
- @obj = Registry.init.start_service :name => options[:service], :params => options[:params]
38
- else
39
- @obj = Registry.init.start_service :name => options[:service]
40
- end
41
- @log = Registry.init.get_service :name => 'logger'
42
- @mapped_service = options[:service]
43
- end
44
-
45
- # method_missing overload to make the class proxy efficient
46
- def method_missing(methodname, *args,&block)
47
- @log.debug("ProxyDebug") { "BEGIN CALL for mapped service #{@mapped_service} "}
48
- @log.debug("ProxyDebug") { "called: #{methodname} " }
49
- @log.debug("ProxyDebug") { "args : #{args.join " "}" }
50
- if block_given? then
51
- @log.debug("ProxyDebug") { "block given" }
52
- a = @obj.send(methodname, *args,&block)
53
- else
54
- a = @obj.send(methodname, *args)
55
- end
56
- @log.debug("ProxyDebug") { "=> returned: #{a} " }
57
- @log.debug("ProxyDebug") { 'END CALL' }
58
- return a
59
- end
60
-
61
-
62
- end
63
- end
64
- end
65
-
66
- # protection for loading libs
67
- if $0 == __FILE__ then
68
- puts "#{File::basename(__FILE__)}:"
69
- puts 'this is a RUBY library file'
70
- puts "Copyright (c) Ultragreen"
71
- end
72
-
73
-
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # $BUILTIN
3
- # $NAME logger
4
- # $SERVICE Carioca::Services::InternalLogger
5
- # $RESOURCE logger
6
- # $DESCRIPTION The standard ruby Logger internal wrapper Service for Carioca
7
- # $INIT_OPTIONS target => /tmp/log.file
8
- # Copyright Ultragreen (c) 2005
9
- #---
10
- # Author : Romain GEORGES
11
- # type : class definition Ruby
12
- # obj : Generic config library
13
- #---
14
- # $Id$
15
-
16
- require 'rubygems'
17
- require 'logger'
18
- require 'methodic'
19
-
20
- module Carioca
21
- module Services
22
-
23
- # Service Logger (InternalLogger) of Carioca,
24
- # @note integrally based on Logger from logger Gem
25
- class InternalLogger < Logger
26
-
27
- private
28
-
29
- # logger service constructor (open log)
30
- # @param [Hash] _options the params
31
- # @option _options [String] :target the filename where to log
32
- def initialize(_options = {})
33
- options = Methodic.get_options(_options)
34
- options.specify_default_value :target => STDOUT
35
- options.merge
36
- super(options[:target])
37
- end
38
-
39
- # garbage service hook
40
- # @note close the logger
41
- def garbage
42
- self.close
43
- end
44
-
45
- end
46
- end
47
-
48
-
49
-
50
- end
51
-
52
-
53
- # interactive hacks
54
- if $0 == __FILE__ then
55
- puts "#{File::basename(__FILE__)}:"
56
- puts 'this is a RUBY library file'
57
- puts "Copyright (c) Ultragreen"
58
- end
@@ -1,143 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #---
3
- # Author : Romain GEORGES
4
- # type : gem component library
5
- # obj : Carioca::Services Module
6
- #---
7
-
8
-
9
-
10
- module Carioca
11
-
12
- # namespace Services for Registry AND buitlins
13
- module Services
14
- # class method returning full path in Carioca gem for builtin services files according to installed gem path.
15
- # @note do not use directly for generale purpose (expert/hacks only)
16
- # @param [String] _name the name of a service
17
- # @return [String,false] the full path filename orfalse if not found
18
- def Services::search_builtins(_name)
19
- if Gem::Specification.respond_to?(:find_by_name)
20
- begin
21
- spec = Gem::Specification.find_by_name('carioca')
22
- rescue LoadError
23
- spec = nil
24
- end
25
- else
26
- spec = Gem.searcher.find('carioca')
27
- end
28
- if spec then
29
- if Gem::Specification.respond_to?(:find_by_name)
30
-
31
- res = spec.lib_dirs_glob.split('/')
32
- else
33
- res = Gem.searcher.lib_dirs_for(spec).split('/')
34
- end
35
- res.pop
36
- services_path = res.join('/').concat('/lib/carioca/services')
37
- else
38
- services_path = "./lib/carioca/services"
39
- end
40
- _file ="#{services_path}/#{_name}.rb"
41
- if ( File::exist? _file or File::exist? "lib/#{_file}" ) then
42
- return _file
43
- else
44
- return false
45
- end
46
- end
47
-
48
- # class method returning the path of a file in gem if exist or false
49
- # @note do not use directly for generale purpose (expert/hacks only)
50
- # @return [String|FalseClass] the full path of a service file
51
- def Services::search_file_in_gem(_gem,_file)
52
- if Gem::Specification.respond_to?(:find_by_name)
53
- begin
54
- spec = Gem::Specification.find_by_name(_gem)
55
- rescue LoadError
56
- spec = nil
57
- end
58
- else
59
- spec = Gem.searcher.find(_gem)
60
- end
61
- if spec then
62
- if Gem::Specification.respond_to?(:find_by_name)
63
- res = spec.lib_dirs_glob.split('/')
64
- else
65
- res = Gem.searcher.lib_dirs_for(spec).split('/')
66
- end
67
- res.pop
68
- services_path = res.join('/').concat("/#{_file}")
69
- return services_path if File::exist?(services_path)
70
- return false
71
- else
72
- return false
73
- end
74
- end
75
-
76
-
77
- # class method returning the [Carioca::Services::Registry]@list complement for builtins service found for a carioca gem version
78
- # @note do not use directly for generale purpose (expert/hacks only)
79
- # @return [Hash] the [Carioca::Services::Registry]@list complement
80
- def Services::discover_builtins
81
- if Gem::Specification.respond_to?(:find_by_name)
82
- begin
83
- spec = Gem::Specification.find_by_name('carioca')
84
- rescue LoadError
85
- spec = nil
86
- end
87
- else
88
- spec = Gem.searcher.find('carioca')
89
- end
90
-
91
- if spec then
92
- if Gem::Specification.respond_to?(:find_by_name)
93
- res = spec.lib_dirs_glob.split('/')
94
- else
95
- res = Gem.searcher.lib_dirs_for(spec).split('/')
96
- end
97
- res.pop
98
- services_path = res.join('/').concat('/lib/carioca/services')
99
- else
100
- services_path = "./lib/carioca/services"
101
- end
102
-
103
- map = Dir["#{services_path}/*"]
104
- map.delete_if { |item| not File::file?(item) }
105
- map.delete_if { |item| File::basename(item) == 'logger.rb' }
106
-
107
- res = {}
108
- map.each do |file|
109
- Services::validate_service(file,res)
110
- end
111
- return res
112
- end
113
-
114
- def Services::validate_service(file,res)
115
- init_options = {}
116
- if open(file).grep(/^# \$BUILTIN/).size > 0 then
117
- service = open(file).grep(/# \$SERVICE/).first.split[2]
118
- resource = open(file).grep(/# \$RESOURCE/).first.split[2]
119
- desc = open(file).grep(/# \$DESCRIPTION/).first
120
- desc = desc.split(' ')
121
- desc.shift(2)
122
- description= desc.join(' ')
123
- open(file).grep(/# \$INIT_OPTIONS/).each do |opt|
124
- prev = opt.split
125
- init_options[prev[2].to_sym] = prev[4]
126
- end
127
- distributed = (open(file).grep(/# \$DISTRIBUTED/))? true : false
128
- req = open(file).grep(/# \$REQUIRES/)
129
- if req.empty? then
130
- requires = []
131
- else
132
- requires = req.split
133
- requires.shift
134
- end
135
-
136
- end
137
- unless service.nil? or resource.nil? or description.nil? then
138
- res[resource] = { :service => service, :type => :builtin, :description => description, :resource => resource}
139
- res[resource][:init_options] = init_options unless init_options.empty?
140
- end
141
- end
142
- end
143
- end
@@ -1,11 +0,0 @@
1
- require 'carioca'
2
- namespace :carioca do
3
- desc "initialize Carioca Registry"
4
- task :init_registry do
5
- mkdir 'services'
6
- carioca = Carioca::Services::Registry.init :name => 'services/registry.yml', :debug => true
7
- carioca.discover_builtins
8
- carioca.save!
9
- puts "Carioca : Registry initialize in services/registry.yml (see /tmp/log.file for details)"
10
- end
11
- end