dorsal 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +26 -0
- data/Rakefile +61 -0
- data/dorsal.gemspec +33 -0
- data/lib/dorsal.rb +53 -0
- data/lib/dorsal/controller.rb +131 -0
- data/lib/dorsal/exceptions.rb +13 -0
- data/lib/dorsal/implementation.rb +151 -0
- data/lib/dorsal/privates.rb +183 -0
- data/lib/dorsal/version.rb +14 -0
- data/spec/dorsal_spec.rb +168 -0
- data/spec/samples/dummy.rb +10 -0
- data/ultragreen_roodi_coding_convention.yml +25 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6b142bf4c6b5a14321f07c27e1de317bbe7bec8e
|
4
|
+
data.tar.gz: 31bbcd213f7c18aac8671d0041c00b6d7657e499
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6dead18e0122a5999e7d6276e709ec05492e3a7abcea00759ab6851bc8bdc1d2f58190225e830e1bbfa5e82a9ce0ac18de4bc8a9e011f270cc715b757a6cde63
|
7
|
+
data.tar.gz: da7218d7a318d41d98ccd3dc814c7f90c0a6f5c4d8f755dbbd703c0150a17684518b8762343f425ccf25e548ec43d8d3a5ec21d01e18171a93ab814b1b5c6b06
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Romain GEORGES
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Dorsal
|
2
|
+
|
3
|
+
* *Authors* : Romain GEORGES
|
4
|
+
* *Email* : romain@ultragreen.net
|
5
|
+
* *Description* : Dorsal : Druby Objects's Ring Server as an simple Alternative to Linda
|
6
|
+
Dorsal provide a simple and easy to use Ring Server for DRuby Objects based services architectures
|
7
|
+
* *Homepage : http://www.ultragreen.net/projects/dorsal
|
8
|
+
* *License : BSD
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'dorsal'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install dorsal
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rake'
|
5
|
+
require "rake/clean"
|
6
|
+
require "rubygems/package_task"
|
7
|
+
require "rdoc/task"
|
8
|
+
require 'code_statistics'
|
9
|
+
require 'rspec/core/rake_task'
|
10
|
+
require 'yard'
|
11
|
+
require 'yard/rake/yardoc_task.rb'
|
12
|
+
require "rake/tasklib"
|
13
|
+
require "roodi"
|
14
|
+
require "roodi_task"
|
15
|
+
|
16
|
+
|
17
|
+
RoodiTask.new() do | t |
|
18
|
+
t.patterns = %w(lib/**/*.rb)
|
19
|
+
t.config = "ultragreen_roodi_coding_convention.yml"
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
CLEAN.include('*.tmp','*.old')
|
24
|
+
CLOBBER.include('*.tmp', 'build/*','#*#')
|
25
|
+
|
26
|
+
|
27
|
+
content = File::readlines(File.join(File.dirname(__FILE__), 'dorsal.gemspec')).join
|
28
|
+
spec = eval(content)
|
29
|
+
|
30
|
+
RSpec::Core::RakeTask.new('spec')
|
31
|
+
|
32
|
+
YARD::Rake::YardocTask.new do |t|
|
33
|
+
t.files = [ 'lib/**/*.rb', '-', 'doc/**/*','spec/**/*_spec.rb']
|
34
|
+
t.options += ['--title', "Gem Documentation"]
|
35
|
+
t.options += ['-o', "yardoc"]
|
36
|
+
t.options += ['-r', "doc/manual.rdoc"]
|
37
|
+
end
|
38
|
+
YARD::Config.load_plugin('yard-rspec')
|
39
|
+
|
40
|
+
namespace :yardoc do
|
41
|
+
task :clobber do
|
42
|
+
rm_r "yardoc" rescue nil
|
43
|
+
rm_r ".yardoc" rescue nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
task :clobber => "yardoc:clobber"
|
47
|
+
|
48
|
+
|
49
|
+
Gem::PackageTask.new(spec) do |pkg|
|
50
|
+
pkg.need_tar = true
|
51
|
+
pkg.need_zip = true
|
52
|
+
end
|
53
|
+
|
54
|
+
Rake::RDocTask.new('rdoc') do |d|
|
55
|
+
d.rdoc_files.include('doc/**/*','bin/*')
|
56
|
+
d.main = 'doc/manual.rdoc'
|
57
|
+
d.title = 'Dorsal : Yard'
|
58
|
+
d.options << '--line-numbers' << '--diagram' << '-SHN'
|
59
|
+
end
|
60
|
+
|
61
|
+
task :default => [:gem]
|
data/dorsal.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dorsal/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dorsal"
|
8
|
+
spec.version = Dorsal::VERSION
|
9
|
+
spec.authors = ["Romain GEORGES"]
|
10
|
+
spec.email = ["romain@ultragreen.net"]
|
11
|
+
spec.description = %q{Dorsal : Druby Objects's Ring Server as an simple Alternative to Linda}
|
12
|
+
spec.summary = %q{Dorsal provide a simple and easy to use Ring Server for DRuby Objects based services architectures}
|
13
|
+
spec.homepage = "http://www.ultragreen.net/projects/dorsal"
|
14
|
+
spec.license = "BSD"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
spec.add_development_dependency('methodic', '>= 1.2')
|
21
|
+
spec.add_development_dependency('rspec')
|
22
|
+
spec.add_development_dependency('yard')
|
23
|
+
spec.add_development_dependency('rdoc')
|
24
|
+
spec.add_development_dependency('roodi')
|
25
|
+
spec.add_development_dependency('code_statistics')
|
26
|
+
spec.add_development_dependency('yard-rspec')
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_dependency "daemons"
|
29
|
+
|
30
|
+
spec.required_ruby_version = '>= 1.8.1'
|
31
|
+
spec.rubyforge_project = "nowarning"
|
32
|
+
spec.has_rdoc = true
|
33
|
+
end
|
data/lib/dorsal.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#---# Author : Romain GEORGES
|
4
|
+
# type : gem component library
|
5
|
+
# obj : Dorsal Module
|
6
|
+
#---
|
7
|
+
require "dorsal/version"
|
8
|
+
require 'rubygems'
|
9
|
+
require 'methodic'
|
10
|
+
require 'drb/drb'
|
11
|
+
require 'dorsal/privates'
|
12
|
+
require 'dorsal/exceptions'
|
13
|
+
require 'dorsal/implementation'
|
14
|
+
require 'dorsal/controller'
|
15
|
+
|
16
|
+
# module Dorsal
|
17
|
+
# @author Romain GEORGES <romain@ultragreen.net>
|
18
|
+
# @see http://www.ultragreen.net/projects/dorsal
|
19
|
+
# @version (See Dorsal::VERSION)
|
20
|
+
# @note this module is a namespace Dorsal
|
21
|
+
module Dorsal
|
22
|
+
|
23
|
+
# the default dir where write pid files
|
24
|
+
DEFAULT_DIR = '/tmp/dorsal'
|
25
|
+
|
26
|
+
# the default host name shared between Ring Server and DRb hosted services
|
27
|
+
DEFAULT_HOST = 'localhost'
|
28
|
+
|
29
|
+
# the default port of the Ring Server
|
30
|
+
DEFAULT_PORT = '8686'
|
31
|
+
|
32
|
+
# the default shortname of the ringserver
|
33
|
+
DEFAULT_RINGSERVER_NAME = 'ringserver'
|
34
|
+
|
35
|
+
# the default long description of the ring Server
|
36
|
+
DEFAULT_RINGSERVER_DESCRIPTION = 'Dorsal Ring Server'
|
37
|
+
|
38
|
+
# the default debug status
|
39
|
+
DEFAULT_DEBUG = false
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#---
|
4
|
+
# Author : Romain GEORGES
|
5
|
+
# type : gem component library
|
6
|
+
# obj : Dorsal Module
|
7
|
+
#---
|
8
|
+
require 'drb'
|
9
|
+
require 'methodic'
|
10
|
+
require 'dorsal/privates'
|
11
|
+
require 'dorsal/exceptions'
|
12
|
+
|
13
|
+
# the Dorsal namespace
|
14
|
+
module Dorsal
|
15
|
+
# the Controller Class, provide access and control of the Ring Server and services, via the Ring Server
|
16
|
+
# @example usage
|
17
|
+
# dorsal = Dorsal::Controller::new
|
18
|
+
# # or
|
19
|
+
# dorsal = Dorsal::Contoller::new :host => 'dorsal.example.com',
|
20
|
+
# :port => "8888", :dir => '/a/writable/path', :description => 'My Own Dorsal Ring Server'
|
21
|
+
class Controller
|
22
|
+
|
23
|
+
# use shared privates
|
24
|
+
include Dorsal::Privates
|
25
|
+
private :start
|
26
|
+
private :stop
|
27
|
+
private :status
|
28
|
+
|
29
|
+
|
30
|
+
# @example read
|
31
|
+
# dorsal = Dorsal::Controller::new
|
32
|
+
# p dorsal.options
|
33
|
+
# @attr_reader [Hash] options a hash table of all structured options of Dorsal
|
34
|
+
attr_reader :options
|
35
|
+
|
36
|
+
# contructor for Dorsal::Controller
|
37
|
+
# @param [Hash] _options (all options are optionals
|
38
|
+
# @note see default values from Dorsal namespace Constants
|
39
|
+
# @option _options [String] :name the name of the ringserver instance
|
40
|
+
# @option _options [String] :description the detail name of the the ring server, use for $0
|
41
|
+
# @option _options [String] :port the port where to bind ring server
|
42
|
+
# @option _options [String] :host the host name share between ring server and hosted DRb services
|
43
|
+
# @option _options [String] :dir a writable path where to write pid files and more.
|
44
|
+
# @option _options [TruClass,FalseClass] :debug to run Dorsal Ring server in foreground, with more traces
|
45
|
+
# @example usage
|
46
|
+
# dorsal = Dorsal::Controller::new
|
47
|
+
# # or
|
48
|
+
# dorsal = Dorsal::Contoller::new :host => 'dorsal.example.com',
|
49
|
+
# :port => "8888", :dir => '/a/writable/path', :description => 'My Own Dorsal Ring Server'
|
50
|
+
def initialize(_options = {})
|
51
|
+
@options = Methodic::get_options(_options)
|
52
|
+
@options.specify_defaults_values :description => Dorsal::DEFAULT_RINGSERVER_DESCRIPTION,
|
53
|
+
:debug => Dorsal::DEFAULT_DEBUG,
|
54
|
+
:host => Dorsal::DEFAULT_HOST,
|
55
|
+
:port => Dorsal::DEFAULT_PORT,
|
56
|
+
:dir => Dorsal::DEFAULT_DIR
|
57
|
+
@options.merge
|
58
|
+
@options[:dir].chomp!('/')
|
59
|
+
@options[:name] = Dorsal::DEFAULT_RINGSERVER_NAME
|
60
|
+
@options[:uri] = "druby://#{options[:host]}:#{options[:port]}"
|
61
|
+
Dir::mkdir(@options[:dir]) unless File::exist?(@options[:dir])
|
62
|
+
@options[:pid_file] = "#{@options[:dir]}/#{@options[:name]}.pid"
|
63
|
+
@options[:object] = Dorsal::ImplementationServer::new({ :dir => @options[:dir], :host => @options[:host], :debug => @options[:debug]})
|
64
|
+
end
|
65
|
+
|
66
|
+
# accessor to ring server if up
|
67
|
+
# @return [DRbObject, nil] the ring server Drb Object if Up or nil
|
68
|
+
# @example usage
|
69
|
+
# dorsal = Dorsal::Controller::new
|
70
|
+
# dorsal.start_ring_server
|
71
|
+
# ring = dorsal.bin_to_ring
|
72
|
+
def bind_to_ring
|
73
|
+
if ring_server_status then
|
74
|
+
DRb.start_service
|
75
|
+
return DRbObject.new nil, @options[:uri]
|
76
|
+
else
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# start the ring server if not
|
82
|
+
# @return [Fixnum, FalseClass] the pid of the ring server or false if already start
|
83
|
+
# @example usage
|
84
|
+
# dorsal = Dorsal::Controller::new
|
85
|
+
# dorsal.start_ring_server #=> a Fixnum for the PID
|
86
|
+
# dorsal.start_ring_server #=> false
|
87
|
+
def start_ring_server
|
88
|
+
unless ring_server_status then
|
89
|
+
res = start(@options) do
|
90
|
+
DRb.start_service(@options[:uri], @options[:object])
|
91
|
+
DRb.thread.join
|
92
|
+
end
|
93
|
+
return res
|
94
|
+
else
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
# stop the ring server if up
|
101
|
+
# @return [TrueClass, FalseClass] true if really shutdown, false otherwise
|
102
|
+
# @example usage
|
103
|
+
# dorsal = Dorsal::Controller::new
|
104
|
+
# dorsal.start_ring_server #=> a Fixnum for the PID
|
105
|
+
# dorsal.stop_ring_server #=> true
|
106
|
+
# dorsal.stop_ring_server #=> false
|
107
|
+
def stop_ring_server
|
108
|
+
if ring_server_status then
|
109
|
+
ring = self.bind_to_ring
|
110
|
+
ring.list_services.keys.each do |service|
|
111
|
+
ring.destroy_service :name => service
|
112
|
+
end
|
113
|
+
return stop @options
|
114
|
+
else
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# return the running status of the ring server
|
120
|
+
# @return [TrueClass, FalseClass] true if up, false if down
|
121
|
+
# @example usage
|
122
|
+
# dorsal = Dorsal::Controller::new
|
123
|
+
# dorsal.start_ring_server #=> a Fixnum for the PID
|
124
|
+
# dorsal.ring_server_status #=> true
|
125
|
+
# dorsal.stop_ring_server #=> true
|
126
|
+
# dorsal.ring_server_status #=> false
|
127
|
+
def ring_server_status
|
128
|
+
return status @options
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#---
|
4
|
+
# Author : Romain GEORGES
|
5
|
+
# type : gem component library
|
6
|
+
# obj : Dorsal Module
|
7
|
+
#---
|
8
|
+
|
9
|
+
# the Dorsal Namespace
|
10
|
+
module Dorsal
|
11
|
+
# Exception class override from servers errors
|
12
|
+
class ServerError < Exception; end
|
13
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#---
|
4
|
+
# Author : Romain GEORGES
|
5
|
+
# type : gem component library
|
6
|
+
# obj : Dorsal Module
|
7
|
+
#---
|
8
|
+
require 'drb'
|
9
|
+
require 'dorsal/privates'
|
10
|
+
|
11
|
+
# the dorsal namespace
|
12
|
+
module Dorsal
|
13
|
+
|
14
|
+
# the Ring Server DRbObject Implementation
|
15
|
+
# @note should NOT be instantiate
|
16
|
+
# @note this classe is made to be instantiate as a ring server
|
17
|
+
# @private
|
18
|
+
class ImplementationServer
|
19
|
+
|
20
|
+
include DRbUndumped
|
21
|
+
include Dorsal::Privates
|
22
|
+
|
23
|
+
# @attr_reader [Hash] data the internal Hash of the ring server
|
24
|
+
# @note for debug only
|
25
|
+
attr_reader :data
|
26
|
+
|
27
|
+
# the contructor of the Ring Server
|
28
|
+
# @param [Hash] _options the params of the constructor, keys must be symbols
|
29
|
+
# @note :description (default) 'Dorsal::DEFAULT_RINGSERVER_DESCRIPTION'
|
30
|
+
# @note :debug (default) 'Dorsal::DEFAULT_DEBUG'
|
31
|
+
# @note :host (default) 'Dorsal::DEFAULT_HOST'
|
32
|
+
# @note :port (default) 'Dorsal::DEFAULT_PORT'
|
33
|
+
# @note :dir (default) 'Dorsal::DEFAULT_DIR'
|
34
|
+
# @note :name (default) 'Dorsal::DEFAULT_RINGSERVER_NAME'
|
35
|
+
# @note :uri rule 'druby://(:host):(:port)'
|
36
|
+
# @note :pid_file rule '(:dir)/(:name).pid'
|
37
|
+
# @option _options [String] :description the description of ring server
|
38
|
+
# @option _options [TrueClass,FalseClass] :debug the deubg mode
|
39
|
+
# @option _options [String] :host the host for ring server and services
|
40
|
+
# @option _options [String] :port the port for the ring server
|
41
|
+
# @option _options [String] :dir the writable path for pids files
|
42
|
+
# @option _options [String] :name the ring server name
|
43
|
+
# @option _options [String] :uri the defined uri for ring server
|
44
|
+
# @option _options [String] :pid_file the defined pid_file for ring server
|
45
|
+
# @note DO NOT USE DIRECTLY
|
46
|
+
def initialize(_options = {})
|
47
|
+
@options = Methodic::get_options(_options)
|
48
|
+
@options.specify_defaults_values :name => 'ringserver',
|
49
|
+
:host => 'localhost',
|
50
|
+
:debug => false,
|
51
|
+
:dir => '/tmp/dorsal'
|
52
|
+
@options.merge
|
53
|
+
@data ={}
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# start a service from the ring server
|
58
|
+
# @return [Fixnum,FalseClass] the pid of the process who host the DRb service, false if already started
|
59
|
+
# @param [Hash] _options the params of the constructor, keys must be symbols
|
60
|
+
# @option _options [String] :name the name of the service
|
61
|
+
# @option _options [String] :description the long name of the service, use for $0
|
62
|
+
# @option _options [Object] :object an object to be served by DRb
|
63
|
+
# @note access by Dorsal::Controller::new.bind_to_ring.start_service
|
64
|
+
# @example usage
|
65
|
+
# Dorsal::Controller::new.bind_to_ring.start_service :name => 'service', :description => 'a service', :object => MyService::new
|
66
|
+
def start_service(_options = {})
|
67
|
+
options = Methodic::get_options(_options)
|
68
|
+
options.specify_presences_of :name, :description, :object
|
69
|
+
options.validate
|
70
|
+
unless @data.include?(options[:name]) then
|
71
|
+
options[:pid_file] = "#{@options[:dir]}/service-#{options[:name]}.pid"
|
72
|
+
options[:uri] = "druby://#{@options[:host]}:#{get_free_port(40000,50000)}"
|
73
|
+
@data[options[:name]] = { :description => options[:description] , :pid_file => options[:pid_file], :uri => options[:uri] }
|
74
|
+
return start(options) do
|
75
|
+
require 'drb'
|
76
|
+
options[:object].extend DRb::DRbUndumped
|
77
|
+
DRb.start_service(options[:uri], options[:object])
|
78
|
+
DRb.thread.join
|
79
|
+
end
|
80
|
+
else
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# stop a service in the ring
|
86
|
+
# @return [TrueClass,FalseClass] true if really stop, false if already down
|
87
|
+
# @param [Hash] _options the params of the constructor, keys must be symbols
|
88
|
+
# @option _options [String] :name the name of the service
|
89
|
+
# @note access by Dorsal::Controller::new.bind_to_ring.destroy_service
|
90
|
+
# @example usage
|
91
|
+
# Dorsal::Controller::new.bind_to_ring.destroy_service :name => 'service'
|
92
|
+
def destroy_service(_options = {})
|
93
|
+
options = Methodic::get_options(_options)
|
94
|
+
options.specify_presences_of :name
|
95
|
+
options.validate
|
96
|
+
if @data.include? options[:name] then
|
97
|
+
options[:pid_file] = @data[options[:name]][:pid_file]
|
98
|
+
options[:description] = @data[options[:name]][:description]
|
99
|
+
if stop(options) then
|
100
|
+
@data.delete(options[:name])
|
101
|
+
return true
|
102
|
+
end
|
103
|
+
return false
|
104
|
+
end
|
105
|
+
return false
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# bind to a service from the ring server
|
110
|
+
# @return [DRbObject,nil] the Distributed Service, nil if service not in the Ring
|
111
|
+
# @param [Hash] _options the params of the constructor, keys must be symbols
|
112
|
+
# @option _options [String] :name the name of the service
|
113
|
+
# @note access by Dorsal::Controller::new.bind_to_ring.bind_to_service
|
114
|
+
# @example usage
|
115
|
+
# Dorsal::Controller::new.bind_to_ring.bind_to_service :name => 'service'
|
116
|
+
def bind_to_service(_options = {})
|
117
|
+
options = Methodic::get_options(_options)
|
118
|
+
options.specify_presences_of :name
|
119
|
+
options.validate
|
120
|
+
if list_services.include?(options[:name]) then
|
121
|
+
DRb.start_service
|
122
|
+
return DRbObject.new nil, @data[options[:name]][:uri]
|
123
|
+
else
|
124
|
+
return nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# list the services from the ring server
|
129
|
+
# @return [Hash] the structured list of services in the ring
|
130
|
+
# @note access by Dorsal::Controller::new.bind_to_ring.list_services
|
131
|
+
# @example usage
|
132
|
+
# Dorsal::Controller::new.bind_to_ring.list_services
|
133
|
+
def list_services
|
134
|
+
return @data
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
# return a free TCP port in range
|
139
|
+
# @param [Fixnum,String] _start the first port (default 40000)
|
140
|
+
# @param [Fixnum,String] _end the last port (default 50000)
|
141
|
+
# @return [fixnum, FalseClass] the port or false if no port found
|
142
|
+
def get_free_port(_start=40000,_end=50000)
|
143
|
+
list = IO.popen("netstat -an|grep tcp|awk '{ print $4}'").readlines.map!{|item| item.chomp! ; item = item.split('.').last}
|
144
|
+
_start.upto(_end) do |port|
|
145
|
+
return port unless list.include?(port.to_s)
|
146
|
+
end
|
147
|
+
return false
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#---
|
4
|
+
# Author : Romain GEORGES
|
5
|
+
# type : gem component library
|
6
|
+
# obj : Dorsal Module
|
7
|
+
#---
|
8
|
+
|
9
|
+
require 'methodic'
|
10
|
+
|
11
|
+
# the Dorsal Namespace
|
12
|
+
module Dorsal
|
13
|
+
|
14
|
+
# module mixin for privates methods for both Controller and ImplementationServer
|
15
|
+
# @private
|
16
|
+
module Privates
|
17
|
+
|
18
|
+
# method for daemonize blocks
|
19
|
+
# @param [Hash] _options the list of options, keys are symbols
|
20
|
+
# @option _options [String] :description the description of the process, use for $0
|
21
|
+
# @option _options [String] :pid_file the pid filenam
|
22
|
+
# @yield a process definion or block given
|
23
|
+
# @example usage inline
|
24
|
+
# require 'dorsal/privates'
|
25
|
+
# class Test
|
26
|
+
# include Dorsal::Privates
|
27
|
+
# private :daemonize
|
28
|
+
# def initialize
|
29
|
+
# @loop = Proc::new do
|
30
|
+
# loop do
|
31
|
+
# sleep 1
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# def run
|
37
|
+
# daemonize({:description => "A loop daemon", :pid_file => '/tmp/pid.file'}, &@loop)
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# @example usage block
|
42
|
+
# require 'dorsal/privates'
|
43
|
+
# class Test
|
44
|
+
# include Dorsal::Privates
|
45
|
+
# private :daemonize
|
46
|
+
# def initialize
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# def run
|
50
|
+
# daemonize :description => "A loop daemon", :pid_file => '/tmp/pid.file' do
|
51
|
+
# loop do
|
52
|
+
# sleep 1
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# @return [Fixnum] pid the pid of the forked processus
|
58
|
+
def daemonize(_options)
|
59
|
+
options = Methodic::get_options(_options)
|
60
|
+
options.specify_presences_of :description, :pid_file
|
61
|
+
options.validate
|
62
|
+
return yield if options[:debug]
|
63
|
+
pid = fork do
|
64
|
+
trap("SIGINT"){ exit! 0 }
|
65
|
+
trap("SIGTERM"){ exit! 0 }
|
66
|
+
trap("SIGHUP"){ exit! 0 }
|
67
|
+
Process.daemon
|
68
|
+
$0 = options[:description]
|
69
|
+
yield
|
70
|
+
end
|
71
|
+
File.open(options[:pid_file],"w"){|f| f.puts pid } if options[:pid_file]
|
72
|
+
return pid
|
73
|
+
end
|
74
|
+
|
75
|
+
# daemonize wrapper to prevent processus cloning
|
76
|
+
# @param [Hash] _options the list of options, keys are symbols
|
77
|
+
# @option _options [String] :description the description of the process, use for $0
|
78
|
+
# @option _options [String] :pid_file the pid filenam
|
79
|
+
# @return [Fixnum] pid the pid of the forked processus
|
80
|
+
# @yield a process definion or block given
|
81
|
+
# @raise [Dorsal::RingServerError] if pid_file exist or processus with the present description
|
82
|
+
# @example usage inline
|
83
|
+
# require 'dorsal/privates'
|
84
|
+
# class Test
|
85
|
+
# include Dorsal::Privates
|
86
|
+
# private :start
|
87
|
+
# private :daemonize
|
88
|
+
# def initialize
|
89
|
+
# @loop = Proc::new do
|
90
|
+
# loop do
|
91
|
+
# sleep 1
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# def run
|
97
|
+
# start({:description => "A loop daemon", :pid_file => '/tmp/pid.file'}, &@loop)
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# @example usage block
|
102
|
+
# require 'dorsal/privates'
|
103
|
+
# class Test
|
104
|
+
# include Dorsal::Privates
|
105
|
+
# private :daemonize
|
106
|
+
# private :start
|
107
|
+
# def initialize
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
# def run
|
111
|
+
# start :description => "A loop daemon", :pid_file => '/tmp/pid.file' do
|
112
|
+
# loop do
|
113
|
+
# sleep 1
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
def start(_options = {})
|
119
|
+
options = Methodic::get_options(_options)
|
120
|
+
options.specify_presences_of :description, :pid_file
|
121
|
+
options.validate
|
122
|
+
raise Dorsal::RingServerError::new('already running, pid file exist') if File::exist?(options[:pid_file])
|
123
|
+
raise Dorsal::RingServerError::new('already running') unless `ps aux|grep ruby|grep -v grep |grep '#{options[:description]}'`.empty?
|
124
|
+
return daemonize(options) do
|
125
|
+
yield
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# stop a running processus
|
130
|
+
# @param [Hash] _options the list of options, keys are symbols
|
131
|
+
# @option _options [String] :description the description of the process, use for $0
|
132
|
+
# @option _options [String] :pid_file the pid filename
|
133
|
+
# @option _options [String] :name the name of the processus (OPTIONAL)
|
134
|
+
# @return [TrueClass,FalseClass] true if a service really closed, false otherwise
|
135
|
+
# @raise [Dorsal::ServerError] if can't close an existant service
|
136
|
+
# @example usage inline
|
137
|
+
# #in the same class
|
138
|
+
# def stop_service
|
139
|
+
# stop :name => 'service', :description => 'A loop daemon', :pid_file => '/tmp/pid.file'
|
140
|
+
# end
|
141
|
+
def stop(_options = {})
|
142
|
+
options = Methodic::get_options(_options)
|
143
|
+
options.specify_presences_of :description, :pid_file
|
144
|
+
options.validate
|
145
|
+
File::unlink(options[:pid_file]) if File::exist?(options[:pid_file])
|
146
|
+
pid = `COLUMNS=160 ps aux|grep ruby|grep -v grep |grep '#{options[:description]}'|awk '{ print $2}'`
|
147
|
+
if pid.empty? then
|
148
|
+
return false
|
149
|
+
else
|
150
|
+
if options[:name] == 'ringserver' then
|
151
|
+
raise Dorsal::ServerError::new('Stopping failed') unless system("kill -TERM #{pid} > /dev/null")
|
152
|
+
else
|
153
|
+
return false unless system("kill -TERM #{pid} > /dev/null")
|
154
|
+
end
|
155
|
+
return true
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# give the status of a processus
|
160
|
+
# @param [Hash] _options the list of options, keys are symbols
|
161
|
+
# @option _options [String] :description the description of the process, use for $0
|
162
|
+
# @option _options [String] :pid_file the pid filename
|
163
|
+
# @option _options [String] :name the name of the processus (OPTIONAL)
|
164
|
+
# @return [TrueClass,FalseClass] true if service running, false otherwise
|
165
|
+
# @example usage inline
|
166
|
+
# #in the same class
|
167
|
+
# def service_status
|
168
|
+
# status :name => 'service', :description => 'A loop daemon', :pid_file => '/tmp/pid.file'
|
169
|
+
# end
|
170
|
+
def status(_options = {})
|
171
|
+
options = Methodic::get_options(_options)
|
172
|
+
options.specify_presences_of :description, :pid_file
|
173
|
+
options.validate
|
174
|
+
pid = `COLUMNS=160 ps aux|grep ruby|grep -v grep |grep '#{options[:description]}'|awk '{ print $2}'`
|
175
|
+
if pid.empty? then
|
176
|
+
return false
|
177
|
+
else
|
178
|
+
File.open(options[:pid_file],"w"){|f| f.puts pid } unless File::exist?(options[:pid_file])
|
179
|
+
return true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/spec/dorsal_spec.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#---
|
4
|
+
# Author : Romain GEORGES
|
5
|
+
# type : Rspec
|
6
|
+
# obj : Dorsal Spec
|
7
|
+
#---
|
8
|
+
require 'dorsal'
|
9
|
+
require './spec/samples/dummy'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.expect_with :rspec do |c|
|
13
|
+
c.syntax = :should
|
14
|
+
end
|
15
|
+
config.mock_with :rspec do |c|
|
16
|
+
c.syntax = :should
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
describe "Dorsal" do
|
22
|
+
before :all do
|
23
|
+
File::unlink('/tmp/dorsal_ringserver.pid') if File::exist?('/tmp/dorsal_ringserver.pid')
|
24
|
+
pid = `ps aux|grep ruby|grep -v grep |grep 'Dorsal Ring Server'|awk '{ print $2}'`
|
25
|
+
unless pid.empty? then
|
26
|
+
res = `kill -TERM #{pid.chomp}`
|
27
|
+
end
|
28
|
+
$controller = Dorsal::Controller::new
|
29
|
+
end
|
30
|
+
|
31
|
+
subject { Dorsal }
|
32
|
+
it { should be_an_instance_of Module}
|
33
|
+
context "Dorsal::Controller" do
|
34
|
+
subject { $controller }
|
35
|
+
it { should be_an_instance_of Dorsal::Controller }
|
36
|
+
context "#initialize" do
|
37
|
+
|
38
|
+
end
|
39
|
+
context "Attributs accessor" do
|
40
|
+
context "#options (RO)" do
|
41
|
+
it { should respond_to :options }
|
42
|
+
it { should_not respond_to :options= }
|
43
|
+
it { subject.options[:debug].should eq false }
|
44
|
+
it { subject.options[:uri].should eq "druby://localhost:8686" }
|
45
|
+
it { subject.options[:object].should be_an_instance_of Dorsal::ImplementationServer }
|
46
|
+
it { subject.options[:pid_file].should eq "/tmp/dorsal/ringserver.pid" }
|
47
|
+
it { subject.options[:name].should eq "ringserver" }
|
48
|
+
it { subject.options[:description].should eq "Dorsal Ring Server" }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
context "Instance Methods" do
|
52
|
+
context "#start_ring_server" do
|
53
|
+
it { should respond_to :start_ring_server }
|
54
|
+
it { subject.start_ring_server.should be_an_instance_of Fixnum }
|
55
|
+
it "should return false if try to start twice" do
|
56
|
+
subject.start_ring_server.should be false
|
57
|
+
end
|
58
|
+
it "should exist an instance process of the Ring server" do
|
59
|
+
pid = `ps aux|grep ruby|grep -v grep |grep 'Dorsal Ring Server'|awk '{ print $2}'`.chomp
|
60
|
+
pid.should_not be_empty
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
context "#bind_to_ring_server" do
|
66
|
+
it { should respond_to :bind_to_ring }
|
67
|
+
it "should be possible to bing distributed Ring Server" do
|
68
|
+
$ring = subject.bind_to_ring
|
69
|
+
end
|
70
|
+
context "Ring server Instance" do
|
71
|
+
it "should be an Instance of DRb::DRbObject" do
|
72
|
+
$ring.should be_an_instance_of DRb::DRbObject
|
73
|
+
end
|
74
|
+
it "should Ring server respond to start_service" do
|
75
|
+
$ring.should respond_to :start_service
|
76
|
+
end
|
77
|
+
it "should start a service" do
|
78
|
+
$ring.start_service({ :name => 'dummy', :object => Dummy::new, :description => 'A dummy distributed service' }).should > 0
|
79
|
+
end
|
80
|
+
it "should exist an instance process of dummy service" do
|
81
|
+
pid = `ps aux|grep ruby|grep -v grep |grep 'A dummy distributed service'|awk '{ print $2}'`.chomp
|
82
|
+
pid.should_not be_empty
|
83
|
+
end
|
84
|
+
it "should Ring server respond to list_services" do
|
85
|
+
$ring.should respond_to :list_services
|
86
|
+
end
|
87
|
+
it "should list_services return a Hash" do
|
88
|
+
$ring.list_services.should be_an_instance_of Hash
|
89
|
+
end
|
90
|
+
it "should list_services include 'dummy' service" do
|
91
|
+
$ring.list_services.should include 'dummy'
|
92
|
+
$ring.list_services['dummy'][:description].should eq 'A dummy distributed service'
|
93
|
+
$ring.list_services['dummy'][:pid_file].should eq '/tmp/dorsal/service-dummy.pid'
|
94
|
+
$ring.list_services['dummy'][:uri].should =~ /druby:\/\/localhost:\d+/
|
95
|
+
end
|
96
|
+
it "should exist pid_file : /tmp/dorsal/service-dummy.pid" do
|
97
|
+
File::exist?('/tmp/dorsal/service-dummy.pid').should be true
|
98
|
+
end
|
99
|
+
it "should ring server respond to bind_to_service" do
|
100
|
+
$ring.should respond_to :bind_to_service
|
101
|
+
end
|
102
|
+
it "should bind the dummy service" do
|
103
|
+
$dummy = $ring.bind_to_service :name => 'dummy'
|
104
|
+
$dummy.should be_an_instance_of DRb::DRbObject
|
105
|
+
$dummy.test.should eq 'OK'
|
106
|
+
end
|
107
|
+
it "should have a running daemon instance of the service dummy" do
|
108
|
+
pid = `ps aux|grep ruby|grep -v grep |grep 'A dummy distributed service'|awk '{ print $2}'`.chomp
|
109
|
+
pid.should_not be_empty
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should ring server respond to destroy_service" do
|
113
|
+
$ring.should respond_to :destroy_service
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should be possible to stop the dummy_service" do
|
118
|
+
res = $ring.destroy_service({ :name => 'dummy'})
|
119
|
+
res.should be true
|
120
|
+
$ring.list_services.should be_empty
|
121
|
+
|
122
|
+
end
|
123
|
+
it "should not exist pid_file : /tmp/dorsal/service-dummy.pid" do
|
124
|
+
File::exist?('/tmp/dorsal/service-dummy.pid').should be false
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should return false if trying to stop again the dummy_service" do
|
128
|
+
$ring.destroy_service({ :name => 'dummy'}).should be false
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
context "#ring_server_status(running)" do
|
135
|
+
it { should respond_to :ring_server_status }
|
136
|
+
it "should respond true" do
|
137
|
+
subject.ring_server_status.should be true
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "#stop_ring_server" do
|
142
|
+
it "should re-start a service dummy for testing auto_destroy when stop Ring Server" do
|
143
|
+
$ring.start_service({ :name => 'dummy', :object => Dummy::new, :description => 'A dummy distributed service' }).should > 0
|
144
|
+
end
|
145
|
+
it { should respond_to :stop_ring_server }
|
146
|
+
it { subject.stop_ring_server.should eq true }
|
147
|
+
it "should no longer exist an instance process of the Ring server" do
|
148
|
+
pid = `ps aux|grep ruby|grep -v grep |grep 'Dorsal Ring Server'|awk '{ print $2}'`.chomp
|
149
|
+
pid.should be_empty
|
150
|
+
end
|
151
|
+
it "should not exist an instance process of dummy service" do
|
152
|
+
pid = `ps aux|grep ruby|grep -v grep |grep 'A dummy distributed service'|awk '{ print $2}'`.chomp
|
153
|
+
pid.should be_empty
|
154
|
+
end
|
155
|
+
it "should not exist pid_file : /tmp/dorsal/service-dummy.pid" do
|
156
|
+
File::exist?('/tmp/dorsal/service-dummy.pid').should be false
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "#ring_server_status(shutdown)" do
|
161
|
+
it "should respond false" do
|
162
|
+
subject.ring_server_status.should be false
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
AssignmentInConditionalCheck:
|
2
|
+
CaseMissingElseCheck:
|
3
|
+
ClassLineCountCheck:
|
4
|
+
line_count: 300
|
5
|
+
ClassNameCheck:
|
6
|
+
pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
|
7
|
+
#ClassVariableCheck:
|
8
|
+
CyclomaticComplexityBlockCheck:
|
9
|
+
complexity: 5
|
10
|
+
CyclomaticComplexityMethodCheck:
|
11
|
+
complexity: 10
|
12
|
+
EmptyRescueBodyCheck:
|
13
|
+
ForLoopCheck:
|
14
|
+
MethodLineCountCheck:
|
15
|
+
line_count: 30
|
16
|
+
MethodNameCheck:
|
17
|
+
pattern: !ruby/regexp /^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
|
18
|
+
# MissingForeignKeyIndexCheck:
|
19
|
+
ModuleLineCountCheck:
|
20
|
+
line_count: 500
|
21
|
+
ModuleNameCheck:
|
22
|
+
pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
|
23
|
+
ParameterNumberCheck:
|
24
|
+
parameter_count: 5
|
25
|
+
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dorsal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Romain GEORGES
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: methodic
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: roodi
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: code_statistics
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: bundler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.3'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: daemons
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: 'Dorsal : Druby Objects''s Ring Server as an simple Alternative to Linda'
|
140
|
+
email:
|
141
|
+
- romain@ultragreen.net
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- Gemfile
|
148
|
+
- LICENSE.txt
|
149
|
+
- README.md
|
150
|
+
- Rakefile
|
151
|
+
- doc/manual.rdoc
|
152
|
+
- dorsal.gemspec
|
153
|
+
- lib/dorsal.rb
|
154
|
+
- lib/dorsal/controller.rb
|
155
|
+
- lib/dorsal/exceptions.rb
|
156
|
+
- lib/dorsal/implementation.rb
|
157
|
+
- lib/dorsal/privates.rb
|
158
|
+
- lib/dorsal/version.rb
|
159
|
+
- spec/dorsal_spec.rb
|
160
|
+
- spec/samples/dummy.rb
|
161
|
+
- ultragreen_roodi_coding_convention.yml
|
162
|
+
homepage: http://www.ultragreen.net/projects/dorsal
|
163
|
+
licenses:
|
164
|
+
- BSD
|
165
|
+
metadata: {}
|
166
|
+
post_install_message:
|
167
|
+
rdoc_options: []
|
168
|
+
require_paths:
|
169
|
+
- lib
|
170
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 1.8.1
|
175
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
requirements: []
|
181
|
+
rubyforge_project: nowarning
|
182
|
+
rubygems_version: 2.4.7
|
183
|
+
signing_key:
|
184
|
+
specification_version: 4
|
185
|
+
summary: Dorsal provide a simple and easy to use Ring Server for DRuby Objects based
|
186
|
+
services architectures
|
187
|
+
test_files:
|
188
|
+
- spec/dorsal_spec.rb
|
189
|
+
- spec/samples/dummy.rb
|