kamerling 0.0.1 → 0.0.2
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 +4 -4
- data/.rubocop.yml +4 -30
- data/Gemfile +1 -0
- data/Gemfile.lock +48 -16
- data/config/reek.yml +0 -4
- data/kamerling.gemspec +4 -3
- data/lib/kamerling.rb +2 -2
- data/lib/kamerling/addr.rb +4 -0
- data/lib/kamerling/client.rb +13 -1
- data/lib/kamerling/core_extensions/main.rb +2 -2
- data/lib/kamerling/handler.rb +13 -8
- data/lib/kamerling/logging.rb +22 -10
- data/lib/kamerling/message.rb +4 -4
- data/lib/kamerling/migrations/1_basic_schema.rb +3 -3
- data/lib/kamerling/net_dispatcher.rb +3 -1
- data/lib/kamerling/project.rb +2 -1
- data/lib/kamerling/registration.rb +11 -1
- data/lib/kamerling/repo.rb +1 -1
- data/lib/kamerling/result.rb +12 -1
- data/lib/kamerling/server_runner.rb +13 -15
- data/lib/kamerling/task.rb +8 -1
- data/lib/kamerling/task_dispatcher.rb +2 -2
- data/lib/kamerling/uuid_entity.rb +15 -0
- data/spec/kamerling/addr_spec.rb +6 -0
- data/spec/kamerling/handler_spec.rb +19 -8
- data/spec/kamerling/logging_spec.rb +9 -2
- data/spec/kamerling/message_spec.rb +2 -2
- data/spec/kamerling/net_dispatcher_spec.rb +2 -2
- data/spec/kamerling/receiver_spec.rb +6 -5
- data/spec/kamerling/registrar_spec.rb +9 -5
- data/spec/kamerling/repo_spec.rb +3 -3
- data/spec/kamerling/server/tcp_spec.rb +1 -1
- data/spec/kamerling/server/udp_spec.rb +1 -1
- data/spec/kamerling/server_runner_spec.rb +4 -4
- data/spec/kamerling/task_dispatcher_spec.rb +3 -3
- data/spec/kamerling/uuid_entity_spec.rb +35 -0
- data/spec/spec_helper.rb +9 -7
- metadata +24 -9
- data/lib/kamerling/uuid_object.rb +0 -79
- data/spec/kamerling/uuid_object_spec.rb +0 -101
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9be4e3ac2863218c3d390f4afb2e80f8da0c93be
|
|
4
|
+
data.tar.gz: 98c18518041d91d383daa9c79c5bd46999de4b75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e1b0aeb3ea6a079fd8999f326e6800edcc9f6b56ad1ab0ed997fbf71223e571ae44a7e8c02dc0f5d7d11c65e4dc98b0eae55be57e532bfd90a8d9e61030a56b6
|
|
7
|
+
data.tar.gz: ffe10141b36930b5bf9b4b904312ca96e62e652b51b35f1fceab122fabd7a77258cd9a137936ce6af9c48fefc5968784f189c619cb3685c53091fea66fabcde0
|
data/.rubocop.yml
CHANGED
|
@@ -1,27 +1,9 @@
|
|
|
1
1
|
AccessModifierIndentation:
|
|
2
2
|
Enabled: false
|
|
3
3
|
|
|
4
|
-
AlignArray:
|
|
5
|
-
Enabled: false
|
|
6
|
-
|
|
7
|
-
AlignHash:
|
|
8
|
-
Enabled: false
|
|
9
|
-
|
|
10
|
-
AlignParameters:
|
|
11
|
-
Enabled: false
|
|
12
|
-
|
|
13
4
|
AndOr:
|
|
14
5
|
Enabled: false
|
|
15
6
|
|
|
16
|
-
CaseEquality:
|
|
17
|
-
Enabled: false
|
|
18
|
-
|
|
19
|
-
ConstantName:
|
|
20
|
-
Enabled: false
|
|
21
|
-
|
|
22
|
-
CyclomaticComplexity:
|
|
23
|
-
Enabled: false
|
|
24
|
-
|
|
25
7
|
Documentation:
|
|
26
8
|
Enabled: false
|
|
27
9
|
|
|
@@ -29,22 +11,14 @@ EndAlignment:
|
|
|
29
11
|
Enabled: false
|
|
30
12
|
|
|
31
13
|
HandleExceptions:
|
|
32
|
-
|
|
14
|
+
Exclude:
|
|
15
|
+
- lib/kamerling/server/sock.rb
|
|
33
16
|
|
|
34
17
|
IndentationWidth:
|
|
35
18
|
Enabled: false
|
|
36
19
|
|
|
37
20
|
MethodDefParentheses:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
MethodName:
|
|
41
|
-
Enabled: false
|
|
42
|
-
|
|
43
|
-
SignalException:
|
|
44
|
-
Enabled: false
|
|
45
|
-
|
|
46
|
-
SpaceAroundOperators:
|
|
47
|
-
Enabled: false
|
|
21
|
+
EnforcedStyle: require_no_parentheses
|
|
48
22
|
|
|
49
23
|
TrailingComma:
|
|
50
|
-
|
|
24
|
+
EnforcedStyleForMultiline: comma
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,34 +1,62 @@
|
|
|
1
|
+
GIT
|
|
2
|
+
remote: git://github.com/solnic/virtus.git
|
|
3
|
+
revision: c31940a63d1a4a2ac30032a0c01a9a217b5f5f82
|
|
4
|
+
specs:
|
|
5
|
+
virtus (1.0.2)
|
|
6
|
+
axiom-types (~> 0.1)
|
|
7
|
+
coercible (~> 1.0)
|
|
8
|
+
descendants_tracker (~> 0.0.3)
|
|
9
|
+
equalizer (~> 0.0.9)
|
|
10
|
+
|
|
1
11
|
PATH
|
|
2
12
|
remote: .
|
|
3
13
|
specs:
|
|
4
|
-
kamerling (0.0.
|
|
14
|
+
kamerling (0.0.2)
|
|
5
15
|
after_do (~> 0.3.0)
|
|
6
16
|
sequel (~> 4.4)
|
|
7
17
|
sinatra (~> 1.4)
|
|
8
18
|
slim (~> 2.0)
|
|
9
19
|
sqlite3 (~> 1.3)
|
|
20
|
+
virtus (~> 1.0)
|
|
10
21
|
|
|
11
22
|
GEM
|
|
12
23
|
remote: https://rubygems.org/
|
|
13
24
|
specs:
|
|
14
25
|
after_do (0.3.0)
|
|
15
26
|
ast (1.1.0)
|
|
27
|
+
atomic (1.1.16)
|
|
28
|
+
axiom-types (0.1.0)
|
|
29
|
+
descendants_tracker (~> 0.0.3)
|
|
30
|
+
ice_nine (~> 0.11.0)
|
|
31
|
+
thread_safe (~> 0.1.3)
|
|
16
32
|
bogus (0.1.4)
|
|
17
33
|
dependor (>= 0.0.4)
|
|
34
|
+
celluloid (0.15.2)
|
|
35
|
+
timers (~> 1.1.0)
|
|
36
|
+
celluloid-io (0.15.0)
|
|
37
|
+
celluloid (>= 0.15.0)
|
|
38
|
+
nio4r (>= 0.5.0)
|
|
39
|
+
coercible (1.0.0)
|
|
40
|
+
descendants_tracker (~> 0.0.1)
|
|
18
41
|
dependor (1.0.1)
|
|
42
|
+
descendants_tracker (0.0.3)
|
|
43
|
+
equalizer (0.0.9)
|
|
19
44
|
ffi (1.9.3)
|
|
45
|
+
ice_nine (0.11.0)
|
|
20
46
|
json (1.8.1)
|
|
21
|
-
listen (
|
|
47
|
+
listen (2.7.1)
|
|
48
|
+
celluloid (>= 0.15.2)
|
|
49
|
+
celluloid-io (>= 0.15.0)
|
|
22
50
|
rb-fsevent (>= 0.9.3)
|
|
23
51
|
rb-inotify (>= 0.9)
|
|
24
|
-
rb-kqueue (>= 0.2)
|
|
25
52
|
mini_portile (0.5.2)
|
|
26
|
-
minitest (5.3.
|
|
53
|
+
minitest (5.3.1)
|
|
27
54
|
minitest-focus (1.1.0)
|
|
28
55
|
minitest (>= 4, < 6)
|
|
56
|
+
nio4r (1.0.0)
|
|
29
57
|
nokogiri (1.6.1)
|
|
30
58
|
mini_portile (~> 0.5.0)
|
|
31
|
-
parser (2.1.
|
|
59
|
+
parser (2.1.7)
|
|
32
60
|
ast (~> 1.1)
|
|
33
61
|
slop (~> 3.4, >= 3.4.5)
|
|
34
62
|
powerpack (0.0.9)
|
|
@@ -42,26 +70,26 @@ GEM
|
|
|
42
70
|
rb-fsevent (0.9.4)
|
|
43
71
|
rb-inotify (0.9.3)
|
|
44
72
|
ffi (>= 0.5.0)
|
|
45
|
-
rb-kqueue (0.2.2)
|
|
46
|
-
ffi (>= 0.5.0)
|
|
47
73
|
reek (1.3.6)
|
|
48
74
|
ruby2ruby (~> 2.0.7)
|
|
49
75
|
ruby_parser (~> 3.2)
|
|
50
76
|
sexp_processor
|
|
51
|
-
rerun (0.
|
|
52
|
-
listen (~>
|
|
53
|
-
rubocop (0.
|
|
77
|
+
rerun (0.9.0)
|
|
78
|
+
listen (~> 2.7)
|
|
79
|
+
rubocop (0.19.1)
|
|
54
80
|
json (>= 1.7.7, < 2)
|
|
55
|
-
parser (~> 2.1.
|
|
81
|
+
parser (~> 2.1.7)
|
|
56
82
|
powerpack (~> 0.0.6)
|
|
57
83
|
rainbow (>= 1.99.1, < 3.0)
|
|
84
|
+
ruby-progressbar (~> 1.4)
|
|
85
|
+
ruby-progressbar (1.4.2)
|
|
58
86
|
ruby2ruby (2.0.7)
|
|
59
87
|
ruby_parser (~> 3.1)
|
|
60
88
|
sexp_processor (~> 4.0)
|
|
61
89
|
ruby_parser (3.4.1)
|
|
62
90
|
sexp_processor (~> 4.1)
|
|
63
|
-
sequel (4.
|
|
64
|
-
sexp_processor (4.4.
|
|
91
|
+
sequel (4.8.0)
|
|
92
|
+
sexp_processor (4.4.2)
|
|
65
93
|
sinatra (1.4.4)
|
|
66
94
|
rack (~> 1.4)
|
|
67
95
|
rack-protection (~> 1.4)
|
|
@@ -69,10 +97,13 @@ GEM
|
|
|
69
97
|
slim (2.0.2)
|
|
70
98
|
temple (~> 0.6.6)
|
|
71
99
|
tilt (>= 1.3.3, < 2.1)
|
|
72
|
-
slop (3.
|
|
100
|
+
slop (3.5.0)
|
|
73
101
|
sqlite3 (1.3.9)
|
|
74
102
|
temple (0.6.7)
|
|
103
|
+
thread_safe (0.1.3)
|
|
104
|
+
atomic
|
|
75
105
|
tilt (1.4.1)
|
|
106
|
+
timers (1.1.0)
|
|
76
107
|
|
|
77
108
|
PLATFORMS
|
|
78
109
|
ruby
|
|
@@ -86,5 +117,6 @@ DEPENDENCIES
|
|
|
86
117
|
rack-test (~> 0.6.2)
|
|
87
118
|
rake (~> 10.1)
|
|
88
119
|
reek (~> 1.3)
|
|
89
|
-
rerun (~> 0.
|
|
90
|
-
rubocop (~> 0.
|
|
120
|
+
rerun (~> 0.9.0)
|
|
121
|
+
rubocop (~> 0.19.0)
|
|
122
|
+
virtus!
|
data/config/reek.yml
CHANGED
data/kamerling.gemspec
CHANGED
|
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
|
6
6
|
gem.license = 'AGPL-3.0'
|
|
7
7
|
gem.name = 'kamerling'
|
|
8
8
|
gem.summary = 'Kamerling: a computation network server'
|
|
9
|
-
gem.version = '0.0.
|
|
9
|
+
gem.version = '0.0.2'
|
|
10
10
|
|
|
11
11
|
gem.files = `git ls-files -z`.split "\0"
|
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map { |path| File.basename path }
|
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
|
|
|
17
17
|
gem.add_dependency 'sinatra', '~> 1.4'
|
|
18
18
|
gem.add_dependency 'slim', '~> 2.0'
|
|
19
19
|
gem.add_dependency 'sqlite3', '~> 1.3'
|
|
20
|
+
gem.add_dependency 'virtus', '~> 1.0'
|
|
20
21
|
|
|
21
22
|
gem.add_development_dependency 'bogus', '~> 0.1.3'
|
|
22
23
|
gem.add_development_dependency 'minitest', '~> 5.0'
|
|
@@ -25,6 +26,6 @@ Gem::Specification.new do |gem|
|
|
|
25
26
|
gem.add_development_dependency 'rack-test', '~> 0.6.2'
|
|
26
27
|
gem.add_development_dependency 'rake', '~> 10.1'
|
|
27
28
|
gem.add_development_dependency 'reek', '~> 1.3'
|
|
28
|
-
gem.add_development_dependency 'rerun', '~> 0.
|
|
29
|
-
gem.add_development_dependency 'rubocop', '~> 0.
|
|
29
|
+
gem.add_development_dependency 'rerun', '~> 0.9.0'
|
|
30
|
+
gem.add_development_dependency 'rubocop', '~> 0.19.0'
|
|
30
31
|
end
|
data/lib/kamerling.rb
CHANGED
|
@@ -20,10 +20,10 @@ require_relative 'kamerling/server/udp'
|
|
|
20
20
|
require_relative 'kamerling/server_runner'
|
|
21
21
|
require_relative 'kamerling/task_dispatcher'
|
|
22
22
|
require_relative 'kamerling/uuid'
|
|
23
|
-
require_relative 'kamerling/
|
|
23
|
+
require_relative 'kamerling/uuid_entity'
|
|
24
24
|
require_relative 'kamerling/client'
|
|
25
25
|
require_relative 'kamerling/project'
|
|
26
26
|
require_relative 'kamerling/registration'
|
|
27
|
-
require_relative 'kamerling/result'
|
|
28
27
|
require_relative 'kamerling/task'
|
|
28
|
+
require_relative 'kamerling/result'
|
|
29
29
|
require_relative 'kamerling/logging'
|
data/lib/kamerling/addr.rb
CHANGED
data/lib/kamerling/client.rb
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
module Kamerling class Client <
|
|
1
|
+
module Kamerling class Client < UUIDEntity
|
|
2
|
+
attribute :addr, Addr
|
|
3
|
+
attribute :busy, Boolean, default: false
|
|
4
|
+
|
|
5
|
+
def self.from_h hash
|
|
6
|
+
super.tap do |client|
|
|
7
|
+
client.addr = Addr[hash[:host], hash[:port], hash[:prot]]
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_h
|
|
12
|
+
super.reject { |key, _| key == :addr }.merge addr.to_h
|
|
13
|
+
end
|
|
2
14
|
end end
|
|
@@ -3,8 +3,8 @@ module Kamerling module CoreExtensions module Main
|
|
|
3
3
|
|
|
4
4
|
def req param
|
|
5
5
|
method = caller.first[/`(.*)'$/, 1]
|
|
6
|
-
callsite = Class
|
|
7
|
-
|
|
6
|
+
callsite = is_a?(Class) ? "#{name}.#{method}" : "#{self.class}##{method}"
|
|
7
|
+
fail "#{callsite}: param #{param} is required"
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def warn_off
|
data/lib/kamerling/handler.rb
CHANGED
|
@@ -6,19 +6,24 @@ module Kamerling class Handler
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def handle input, addr
|
|
9
|
-
|
|
9
|
+
process Message.new(input), addr
|
|
10
|
+
rescue Message::UnknownType => exception
|
|
11
|
+
raise UnknownInput, exception.message
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :receiver, :registrar
|
|
15
|
+
private :receiver, :registrar
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def process message, addr
|
|
10
20
|
case message.type
|
|
11
21
|
when :RGST
|
|
12
22
|
registrar.register addr: addr, client_uuid: message.client_uuid,
|
|
13
|
-
|
|
23
|
+
project_uuid: message.project_uuid
|
|
14
24
|
when :RSLT
|
|
15
25
|
receiver.receive addr: addr, client_uuid: message.client_uuid,
|
|
16
|
-
|
|
26
|
+
data: message.payload, task_uuid: message.task_uuid
|
|
17
27
|
end
|
|
18
|
-
rescue Message::UnknownType => exception
|
|
19
|
-
raise UnknownInput, exception.message
|
|
20
28
|
end
|
|
21
|
-
|
|
22
|
-
attr_reader :receiver, :registrar
|
|
23
|
-
private :receiver, :registrar
|
|
24
29
|
end end
|
data/lib/kamerling/logging.rb
CHANGED
|
@@ -4,17 +4,29 @@ require 'logger'
|
|
|
4
4
|
module Kamerling module Logging
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
-
def log_to logger
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
def log_to logger = Logger.new($stdout)
|
|
8
|
+
log_dispatcher_to logger
|
|
9
|
+
log_server_to logger
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def log_dispatcher_to logger
|
|
16
|
+
NetDispatcher.singleton_class.extend AfterDo
|
|
17
|
+
NetDispatcher.singleton_class.before :dispatch do |addr, bytes|
|
|
18
|
+
logger.debug "sent #{addr} #{bytes}"
|
|
19
|
+
end
|
|
15
20
|
end
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
|
|
22
|
+
def log_server_to logger
|
|
23
|
+
Server::Sock.extend AfterDo
|
|
24
|
+
Server::Sock.before(:start) { |srv| logger.info "start #{srv.addr}" }
|
|
25
|
+
Server::Sock.after(:stop) { |srv| logger.info "stop #{srv.addr}" }
|
|
26
|
+
Server::Sock.before :handle do |input, client_addr|
|
|
27
|
+
logger.info "connect #{client_addr}"
|
|
28
|
+
logger.debug "received #{client_addr} #{input}"
|
|
29
|
+
end
|
|
18
30
|
end
|
|
19
31
|
end
|
|
20
32
|
end end
|
data/lib/kamerling/message.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
module Kamerling class Message
|
|
2
|
-
KnownTypes = %w[DATA PING RGST RSLT]
|
|
3
2
|
UnknownType = Class.new RuntimeError
|
|
4
3
|
|
|
5
|
-
def self.[]
|
|
6
|
-
project: req(:project), task: req(:task), type: req(:type)
|
|
4
|
+
def self.[] client: req(:client), payload: req(:payload),
|
|
5
|
+
project: req(:project), task: req(:task), type: req(:type)
|
|
7
6
|
new "#{type}\0\0\0\0\0\0\0\0\0\0\0\0" + UUID.bin(client.uuid) +
|
|
8
7
|
UUID.bin(project.uuid) + UUID.bin(task.uuid) + payload
|
|
9
8
|
end
|
|
@@ -11,7 +10,8 @@ module Kamerling class Message
|
|
|
11
10
|
def initialize raw
|
|
12
11
|
@raw = raw
|
|
13
12
|
type = raw[0..3]
|
|
14
|
-
|
|
13
|
+
known_types = %w(DATA PING RGST RSLT)
|
|
14
|
+
fail UnknownType, type unless known_types.include? type or type.empty?
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def == other
|
|
@@ -19,9 +19,9 @@ Sequel.migration do
|
|
|
19
19
|
integer :port, null: false
|
|
20
20
|
string :prot, null: false
|
|
21
21
|
foreign_key :client_uuid, :clients, index: true, null: false,
|
|
22
|
-
|
|
22
|
+
type: :uuid
|
|
23
23
|
foreign_key :project_uuid, :projects, index: true, null: false,
|
|
24
|
-
|
|
24
|
+
type: :uuid
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
create_table :results do
|
|
@@ -39,7 +39,7 @@ Sequel.migration do
|
|
|
39
39
|
boolean :done, null: false
|
|
40
40
|
bytea :data, null: false
|
|
41
41
|
foreign_key :project_uuid, :projects, index: true, null: false,
|
|
42
|
-
|
|
42
|
+
type: :uuid
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
data/lib/kamerling/project.rb
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
module Kamerling class Registration <
|
|
1
|
+
module Kamerling class Registration < UUIDEntity
|
|
2
|
+
attribute :addr, Addr
|
|
3
|
+
attribute :client, Client
|
|
4
|
+
attribute :project, Project
|
|
5
|
+
|
|
6
|
+
def to_h
|
|
7
|
+
super
|
|
8
|
+
.reject { |key, _| key == :addr }.merge(addr.to_h)
|
|
9
|
+
.reject { |key, _| key == :client }.merge(client_uuid: client.uuid)
|
|
10
|
+
.reject { |key, _| key == :project }.merge project_uuid: project.uuid
|
|
11
|
+
end
|
|
2
12
|
end end
|
data/lib/kamerling/repo.rb
CHANGED
data/lib/kamerling/result.rb
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
module Kamerling class Result <
|
|
1
|
+
module Kamerling class Result < UUIDEntity
|
|
2
|
+
attribute :addr, Addr
|
|
3
|
+
attribute :client, Client
|
|
4
|
+
attribute :data, String
|
|
5
|
+
attribute :task, Task
|
|
6
|
+
|
|
7
|
+
def to_h
|
|
8
|
+
super
|
|
9
|
+
.reject { |key, _| key == :addr }.merge(addr.to_h)
|
|
10
|
+
.reject { |key, _| key == :client }.merge(client_uuid: client.uuid)
|
|
11
|
+
.reject { |key, _| key == :task }.merge task_uuid: task.uuid
|
|
12
|
+
end
|
|
2
13
|
end end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
require 'optparse'
|
|
2
2
|
|
|
3
3
|
module Kamerling class ServerRunner
|
|
4
|
-
Settings = Struct.new(*%i[db host http tcp udp])
|
|
5
|
-
|
|
6
4
|
def initialize args, classes: def_classes, orm: Sequel, repos: Repos
|
|
7
5
|
@args = args
|
|
8
6
|
repos.db = orm.connect settings.db
|
|
@@ -26,24 +24,24 @@ module Kamerling class ServerRunner
|
|
|
26
24
|
|
|
27
25
|
private
|
|
28
26
|
|
|
27
|
+
Settings = Struct.new(*%i(db host http tcp udp))
|
|
28
|
+
|
|
29
29
|
def def_classes
|
|
30
30
|
{ http: Server::HTTP, tcp: Server::TCP, udp: Server::UDP }
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def defaults
|
|
34
|
+
Settings.new 'sqlite::memory:', '127.0.0.1'
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
def settings
|
|
34
|
-
@settings ||=
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
opts.on("--host #{sets.host}", String, 'server host') do |host|
|
|
42
|
-
sets.host = host
|
|
43
|
-
end
|
|
44
|
-
opts.on('--http 0', Integer, 'HTTP port') { |http| sets.http = http }
|
|
45
|
-
opts.on('--tcp 0', Integer, 'TCP port') { |tcp| sets.tcp = tcp }
|
|
46
|
-
opts.on('--udp 0', Integer, 'UDP port') { |udp| sets.udp = udp }
|
|
38
|
+
@settings ||= defaults.tap do |set|
|
|
39
|
+
OptionParser.new do |opt|
|
|
40
|
+
opt.on("--db #{set.db}", String, 'database') { |db| set.db = db }
|
|
41
|
+
opt.on("--host #{set.host}", String, 'host') { |host| set.host = host }
|
|
42
|
+
opt.on('--http 0', Integer, 'HTTP port') { |http| set.http = http }
|
|
43
|
+
opt.on('--tcp 0', Integer, 'TCP port') { |tcp| set.tcp = tcp }
|
|
44
|
+
opt.on('--udp 0', Integer, 'UDP port') { |udp| set.udp = udp }
|
|
47
45
|
end.parse! args
|
|
48
46
|
end
|
|
49
47
|
end
|
data/lib/kamerling/task.rb
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
module Kamerling class Task <
|
|
1
|
+
module Kamerling class Task < UUIDEntity
|
|
2
|
+
attribute :data, String
|
|
3
|
+
attribute :done, Boolean, default: false
|
|
4
|
+
attribute :project, Project
|
|
5
|
+
|
|
6
|
+
def to_h
|
|
7
|
+
super.reject { |key, _| key == :project }.merge project_uuid: project.uuid
|
|
8
|
+
end
|
|
2
9
|
end end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Kamerling class TaskDispatcher
|
|
2
|
-
def initialize net_dispatcher: NetDispatcher
|
|
2
|
+
def initialize net_dispatcher: NetDispatcher, repos: Repos
|
|
3
3
|
@net_dispatcher = net_dispatcher
|
|
4
4
|
@repos = repos
|
|
5
5
|
end
|
|
@@ -21,7 +21,7 @@ module Kamerling class TaskDispatcher
|
|
|
21
21
|
def dispatch_task client: req(:client), project: req(:project),
|
|
22
22
|
task: req(:task)
|
|
23
23
|
message = Message[client: client, payload: task.data, project: project,
|
|
24
|
-
|
|
24
|
+
task: task, type: :DATA]
|
|
25
25
|
net_dispatcher.dispatch client.addr, message.to_s
|
|
26
26
|
client.busy = true
|
|
27
27
|
repos << client
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'virtus'
|
|
2
|
+
|
|
3
|
+
module Kamerling class UUIDEntity
|
|
4
|
+
include Equalizer.new :uuid
|
|
5
|
+
|
|
6
|
+
include Virtus.model
|
|
7
|
+
|
|
8
|
+
attribute :uuid, String, default: -> * { UUID.new }
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
alias_method :from_h, :new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
alias_method :to_h, :attributes
|
|
15
|
+
end end
|
data/spec/kamerling/addr_spec.rb
CHANGED
|
@@ -19,6 +19,12 @@ module Kamerling describe Addr do
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
describe '#to_h' do
|
|
23
|
+
it 'returns a Hash with Integer and String values' do
|
|
24
|
+
addr.to_h.must_equal host: 'localhost', port: 1981, prot: 'TCP'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
22
28
|
describe '#to_s' do
|
|
23
29
|
it 'returns the Addr in ‘host:port (protocol)’ notation' do
|
|
24
30
|
addr.to_s.must_equal 'localhost:1981 (TCP)'
|
|
@@ -7,19 +7,30 @@ module Kamerling describe Handler do
|
|
|
7
7
|
|
|
8
8
|
it 'handles RGST inputs' do
|
|
9
9
|
input = 'RGST' + "\0" * 12 + '16B client UUID16B project UUID'
|
|
10
|
+
client_uuid = UUID['16B client UUID']
|
|
11
|
+
project_uuid = UUID['16B project UUID']
|
|
10
12
|
handler.handle input, addr
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
args = {
|
|
14
|
+
addr: addr,
|
|
15
|
+
client_uuid: client_uuid,
|
|
16
|
+
project_uuid: project_uuid,
|
|
17
|
+
}
|
|
18
|
+
registrar.must_have_received :register, [args]
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
it 'handles RSLT inputs' do
|
|
17
|
-
input = 'RSLT' + "\0" * 12
|
|
18
|
-
|
|
22
|
+
input = 'RSLT' + "\0" * 12 +
|
|
23
|
+
'16B client UUID16B project UUID16B task UUIDdata'
|
|
24
|
+
client_uuid = UUID['16B client UUID']
|
|
25
|
+
task_uuid = UUID['16B task UUID']
|
|
19
26
|
handler.handle input, addr
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
args = {
|
|
28
|
+
addr: addr,
|
|
29
|
+
client_uuid: client_uuid,
|
|
30
|
+
data: 'data',
|
|
31
|
+
task_uuid: task_uuid,
|
|
32
|
+
}
|
|
33
|
+
receiver.must_have_received :receive, [args]
|
|
23
34
|
end
|
|
24
35
|
|
|
25
36
|
it 'raises on unknown inputs' do
|
|
@@ -8,7 +8,7 @@ module Kamerling describe Logging do
|
|
|
8
8
|
let(:udp_server) { Server::UDP.new addr: Addr['localhost', 1979, :UDP] }
|
|
9
9
|
|
|
10
10
|
before do
|
|
11
|
-
Logging.log_to logger
|
|
11
|
+
Logging.log_to logger
|
|
12
12
|
tcp_server.start
|
|
13
13
|
udp_server.start
|
|
14
14
|
end
|
|
@@ -18,7 +18,7 @@ module Kamerling describe Logging do
|
|
|
18
18
|
udp_server.stop
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
describe '.
|
|
21
|
+
describe '.log_to' do
|
|
22
22
|
it 'logs TCP server starts' do
|
|
23
23
|
logged.must_include 'start localhost:1981 (TCP)'
|
|
24
24
|
end
|
|
@@ -69,5 +69,12 @@ module Kamerling describe Logging do
|
|
|
69
69
|
run_all_threads
|
|
70
70
|
logged.must_include "received #{udp_addr} PING"
|
|
71
71
|
end
|
|
72
|
+
|
|
73
|
+
it 'logs packet dispatches' do
|
|
74
|
+
server = UDPSocket.new.tap { |s| s.bind '127.0.0.1', 0 }
|
|
75
|
+
addr = Addr[server.addr[3], server.addr[1], :UDP]
|
|
76
|
+
NetDispatcher.dispatch addr, 'PING'
|
|
77
|
+
logged.must_include "sent #{addr} PING"
|
|
78
|
+
end
|
|
72
79
|
end
|
|
73
80
|
end end
|
|
@@ -12,7 +12,7 @@ module Kamerling describe Message do
|
|
|
12
12
|
project = fake :project, uuid: UUID.new
|
|
13
13
|
task = fake :task, uuid: UUID.new
|
|
14
14
|
message = Message[client: client, payload: 'pay', project: project,
|
|
15
|
-
|
|
15
|
+
task: task, type: :DATA]
|
|
16
16
|
message.client_uuid.must_equal client.uuid
|
|
17
17
|
message.project_uuid.must_equal project.uuid
|
|
18
18
|
message.task_uuid.must_equal task.uuid
|
|
@@ -57,7 +57,7 @@ module Kamerling describe Message do
|
|
|
57
57
|
|
|
58
58
|
describe '#to_s' do
|
|
59
59
|
it 'returns the raw bytes' do
|
|
60
|
-
mess.to_s.must_equal "#{mess.type}\0\0\0\0\0\0\0\0\0\0\0\0"
|
|
60
|
+
mess.to_s.must_equal "#{mess.type}\0\0\0\0\0\0\0\0\0\0\0\0" \
|
|
61
61
|
'16B client UUID16B project UUID16B task UUIDsome payload'
|
|
62
62
|
end
|
|
63
63
|
end
|
|
@@ -6,7 +6,7 @@ module Kamerling describe NetDispatcher do
|
|
|
6
6
|
server = TCPServer.open 0
|
|
7
7
|
thread = Thread.new { server.accept.read }
|
|
8
8
|
addr = Addr[server.addr[3], server.addr[1], :TCP]
|
|
9
|
-
NetDispatcher.
|
|
9
|
+
NetDispatcher.dispatch addr, 'foo'
|
|
10
10
|
thread.value.must_equal 'foo'
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ module Kamerling describe NetDispatcher do
|
|
|
14
14
|
server = UDPSocket.new.tap { |s| s.bind '127.0.0.1', 0 }
|
|
15
15
|
thread = Thread.new { server.recvfrom(2**16).first }
|
|
16
16
|
addr = Addr[server.addr[3], server.addr[1], :UDP]
|
|
17
|
-
NetDispatcher.
|
|
17
|
+
NetDispatcher.dispatch addr, 'foo'
|
|
18
18
|
thread.value.must_equal 'foo'
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -10,13 +10,14 @@ module Kamerling describe Receiver do
|
|
|
10
10
|
stub(repos).[](Client) { fake :repo, :[] => client }
|
|
11
11
|
stub(repos).[](Task) { fake :repo, :[] => task }
|
|
12
12
|
Receiver.new.receive addr: addr, client_uuid: client.uuid, data: 'data',
|
|
13
|
-
|
|
13
|
+
repos: repos, task_uuid: task.uuid
|
|
14
|
+
result = Result.new addr: addr, client: client, data: 'data', task: task,
|
|
15
|
+
uuid: anything
|
|
14
16
|
client.must_have_received :busy=, [false]
|
|
15
17
|
task.must_have_received :done=, [true]
|
|
16
|
-
repos.must_have_received
|
|
17
|
-
repos.must_have_received
|
|
18
|
-
repos.must_have_received
|
|
19
|
-
data: 'data', task: task, uuid: anything)]
|
|
18
|
+
repos.must_have_received :<<, [client]
|
|
19
|
+
repos.must_have_received :<<, [task]
|
|
20
|
+
repos.must_have_received :<<, [result]
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
end end
|
|
@@ -5,12 +5,16 @@ module Kamerling describe Registrar do
|
|
|
5
5
|
fakes :addr, :client, :project, :repo
|
|
6
6
|
|
|
7
7
|
it 'registers that the given client can do the given project' do
|
|
8
|
-
repos = {
|
|
9
|
-
|
|
8
|
+
repos = {
|
|
9
|
+
Client => { client.uuid => client },
|
|
10
|
+
Project => { project.uuid => project },
|
|
11
|
+
Registration => repo,
|
|
12
|
+
}
|
|
10
13
|
Registrar.new.register addr: addr, client_uuid: client.uuid,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
project_uuid: project.uuid, repos: repos
|
|
15
|
+
registration = Registration.new addr: addr, client: client,
|
|
16
|
+
project: project, uuid: anything
|
|
17
|
+
repo.must_have_received :<<, [registration]
|
|
14
18
|
end
|
|
15
19
|
end
|
|
16
20
|
end end
|
data/spec/kamerling/repo_spec.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require_relative '../spec_helper'
|
|
2
2
|
|
|
3
3
|
module Kamerling describe Repo do
|
|
4
|
-
Tune =
|
|
4
|
+
Tune = Class.new(UUIDEntity) { attribute :genre, Symbol }
|
|
5
5
|
|
|
6
6
|
describe '#<<' do
|
|
7
7
|
it 'passes the Hash version of an object to the source' do
|
|
@@ -15,7 +15,7 @@ module Kamerling describe Repo do
|
|
|
15
15
|
dataset = fake Sequel::Dataset
|
|
16
16
|
source = fake Sequel::Dataset
|
|
17
17
|
tune = Tune.new genre: :chap_hop
|
|
18
|
-
stub(source).<<(tune.to_h) {
|
|
18
|
+
stub(source).<<(tune.to_h) { fail Sequel::UniqueConstraintViolation }
|
|
19
19
|
stub(source).where(uuid: tune.uuid) { dataset }
|
|
20
20
|
Repo.new(Tune, source) << tune
|
|
21
21
|
dataset.must_have_received :update, [tune.to_h]
|
|
@@ -39,7 +39,7 @@ module Kamerling describe Repo do
|
|
|
39
39
|
it 'returns all objects' do
|
|
40
40
|
tune = Tune.new genre: :chap_hop, uuid: UUID.new
|
|
41
41
|
source = fake Sequel::Dataset,
|
|
42
|
-
|
|
42
|
+
all: [{ genre: :chap_hop, uuid: tune.uuid }]
|
|
43
43
|
Repo.new(Tune, source).all.must_equal [tune]
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -30,7 +30,7 @@ module Kamerling describe Server::TCP do
|
|
|
30
30
|
it 'doesn’t blow up on unknown inputs' do
|
|
31
31
|
server = Server::TCP.new addr: addr, handler: handler = fake(:handler)
|
|
32
32
|
server.start
|
|
33
|
-
stub(handler).handle('foo', any(Addr)) {
|
|
33
|
+
stub(handler).handle('foo', any(Addr)) { fail Handler::UnknownInput }
|
|
34
34
|
TCPSocket.open(*server.addr) { |socket| socket << 'foo' }
|
|
35
35
|
server.stop
|
|
36
36
|
end
|
|
@@ -22,7 +22,7 @@ module Kamerling describe Server::UDP do
|
|
|
22
22
|
it 'doesn’t blow up on unknown inputs' do
|
|
23
23
|
server = Server::UDP.new addr: addr, handler: handler = fake(:handler)
|
|
24
24
|
server.start
|
|
25
|
-
stub(handler).handle('foo', any(Addr)) {
|
|
25
|
+
stub(handler).handle('foo', any(Addr)) { fail Handler::UnknownInput }
|
|
26
26
|
UDPSocket.new.send 'foo', 0, *server.addr
|
|
27
27
|
run_all_threads
|
|
28
28
|
server.stop
|
|
@@ -20,7 +20,7 @@ module Kamerling describe ServerRunner do
|
|
|
20
20
|
|
|
21
21
|
describe '.new' do
|
|
22
22
|
it 'hooks to the given database' do
|
|
23
|
-
args = %w
|
|
23
|
+
args = %w(--host 0.0.0.0 --db sqlite::memory:)
|
|
24
24
|
db = fake { Sequel::SQLite::Database }
|
|
25
25
|
orm = fake :sequel, as: :class
|
|
26
26
|
stub(orm).connect('sqlite::memory:') { db }
|
|
@@ -32,7 +32,7 @@ module Kamerling describe ServerRunner do
|
|
|
32
32
|
|
|
33
33
|
describe '#join' do
|
|
34
34
|
it 'joins all the created servers' do
|
|
35
|
-
args = %w
|
|
35
|
+
args = %w(--host 0.0.0.0 --http 1234)
|
|
36
36
|
ServerRunner.new(args, classes: classes).join
|
|
37
37
|
http.must_have_received :join, []
|
|
38
38
|
tcp.wont_have_received :join, []
|
|
@@ -42,7 +42,7 @@ module Kamerling describe ServerRunner do
|
|
|
42
42
|
|
|
43
43
|
describe '#start' do
|
|
44
44
|
it 'starts the servers based on the given command-line parameters' do
|
|
45
|
-
args = %w
|
|
45
|
+
args = %w(--host 0.0.0.0 --http 1234 --tcp 3456 --udp 5678)
|
|
46
46
|
ServerRunner.new(args, classes: classes).start
|
|
47
47
|
http.must_have_received :start, []
|
|
48
48
|
tcp.must_have_received :start, []
|
|
@@ -50,7 +50,7 @@ module Kamerling describe ServerRunner do
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it 'starts only the servers for which the port was given' do
|
|
53
|
-
args = %w
|
|
53
|
+
args = %w(--host 0.0.0.0 --http 1234)
|
|
54
54
|
ServerRunner.new(args, classes: classes).start
|
|
55
55
|
http.must_have_received :start, []
|
|
56
56
|
tcp.wont_have_received :start, []
|
|
@@ -10,12 +10,12 @@ module Kamerling describe TaskDispatcher do
|
|
|
10
10
|
repos = fake :repos, as: :class, projects: [project]
|
|
11
11
|
stub(repos).next_task_for(project) { task }
|
|
12
12
|
stub(repos).free_clients_for(project) { [client] }
|
|
13
|
-
net_dispatcher = fake :net_dispatcher
|
|
13
|
+
net_dispatcher = fake :net_dispatcher, as: :class
|
|
14
14
|
|
|
15
15
|
TaskDispatcher.new(net_dispatcher: net_dispatcher, repos: repos).dispatch
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
header = "DATA#{"\0" * 12}16B client UUID16B project UUID16B task "
|
|
18
|
+
net_dispatcher.must_have_received :dispatch, [addr, header + 'UUIDdata']
|
|
19
19
|
client.must_have_received :busy=, [true]
|
|
20
20
|
repos.must_have_received :<<, [client]
|
|
21
21
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
|
|
3
|
+
module Kamerling describe UUIDEntity do
|
|
4
|
+
describe '.from_h' do
|
|
5
|
+
it 'deserialises the object from a Hash' do
|
|
6
|
+
Trivial = Class.new(UUIDEntity) { attribute :question, Symbol }
|
|
7
|
+
Trivial.from_h(question: :answer).question.must_equal :answer
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe '.new' do
|
|
12
|
+
it 'creates a class with an UUID property defaulting to a random UUID' do
|
|
13
|
+
AttrLess = Class.new UUIDEntity
|
|
14
|
+
AttrLess.new.uuid.must_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/)
|
|
15
|
+
AttrLess.new.uuid.wont_equal AttrLess.new.uuid
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#==' do
|
|
20
|
+
it 'reports UUID-based euqality' do
|
|
21
|
+
Actor = Class.new(UUIDEntity) { attribute :name, Symbol }
|
|
22
|
+
Actor.new(name: :laurel).wont_equal Actor.new name: :laurel
|
|
23
|
+
uuid = UUID.new
|
|
24
|
+
Actor.new(name: :laurel, uuid: uuid)
|
|
25
|
+
.must_equal Actor.new name: :hardy, uuid: uuid
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#to_h' do
|
|
30
|
+
it 'serialises the object to a Hash' do
|
|
31
|
+
Hashble = Class.new(UUIDEntity) { attribute :param, Symbol }
|
|
32
|
+
Hashble.new(param: :val).to_h.must_equal param: :val, uuid: any(String)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -9,14 +9,16 @@ require 'kamerling'
|
|
|
9
9
|
|
|
10
10
|
Bogus.configure { |config| config.search_modules << Kamerling }
|
|
11
11
|
|
|
12
|
-
module
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
end
|
|
12
|
+
module Minitest
|
|
13
|
+
class Spec
|
|
14
|
+
include Rack::Test::Methods
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
module DSL
|
|
17
|
+
def fakes *args
|
|
18
|
+
args.map { |arg| fake arg }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
Thread.abort_on_exception = true
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kamerling
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Piotr Szotkowski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-03-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: after_do
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '1.3'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: virtus
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: bogus
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -184,28 +198,28 @@ dependencies:
|
|
|
184
198
|
requirements:
|
|
185
199
|
- - "~>"
|
|
186
200
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: 0.
|
|
201
|
+
version: 0.9.0
|
|
188
202
|
type: :development
|
|
189
203
|
prerelease: false
|
|
190
204
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
205
|
requirements:
|
|
192
206
|
- - "~>"
|
|
193
207
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: 0.
|
|
208
|
+
version: 0.9.0
|
|
195
209
|
- !ruby/object:Gem::Dependency
|
|
196
210
|
name: rubocop
|
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
|
198
212
|
requirements:
|
|
199
213
|
- - "~>"
|
|
200
214
|
- !ruby/object:Gem::Version
|
|
201
|
-
version: 0.
|
|
215
|
+
version: 0.19.0
|
|
202
216
|
type: :development
|
|
203
217
|
prerelease: false
|
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
219
|
requirements:
|
|
206
220
|
- - "~>"
|
|
207
221
|
- !ruby/object:Gem::Version
|
|
208
|
-
version: 0.
|
|
222
|
+
version: 0.19.0
|
|
209
223
|
description: A network server for distributing computations across different clients
|
|
210
224
|
speaking TCP or UDP.
|
|
211
225
|
email: p.szotkowski@tele.pw.edu.pl
|
|
@@ -250,7 +264,7 @@ files:
|
|
|
250
264
|
- lib/kamerling/task.rb
|
|
251
265
|
- lib/kamerling/task_dispatcher.rb
|
|
252
266
|
- lib/kamerling/uuid.rb
|
|
253
|
-
- lib/kamerling/
|
|
267
|
+
- lib/kamerling/uuid_entity.rb
|
|
254
268
|
- lib/kamerling/views/clients.slim
|
|
255
269
|
- lib/kamerling/views/layout.slim
|
|
256
270
|
- lib/kamerling/views/project.slim
|
|
@@ -274,7 +288,7 @@ files:
|
|
|
274
288
|
- spec/kamerling/server_runner_spec.rb
|
|
275
289
|
- spec/kamerling/task_dispatcher_spec.rb
|
|
276
290
|
- spec/kamerling/task_spec.rb
|
|
277
|
-
- spec/kamerling/
|
|
291
|
+
- spec/kamerling/uuid_entity_spec.rb
|
|
278
292
|
- spec/kamerling/uuid_spec.rb
|
|
279
293
|
- spec/spec_helper.rb
|
|
280
294
|
homepage: https://github.com/chastell/kamerling
|
|
@@ -320,6 +334,7 @@ test_files:
|
|
|
320
334
|
- spec/kamerling/server_runner_spec.rb
|
|
321
335
|
- spec/kamerling/task_dispatcher_spec.rb
|
|
322
336
|
- spec/kamerling/task_spec.rb
|
|
323
|
-
- spec/kamerling/
|
|
337
|
+
- spec/kamerling/uuid_entity_spec.rb
|
|
324
338
|
- spec/kamerling/uuid_spec.rb
|
|
325
339
|
- spec/spec_helper.rb
|
|
340
|
+
has_rdoc:
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
module Kamerling
|
|
2
|
-
def self.UUIDObject *params
|
|
3
|
-
class_definition_from attrs_from params
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
private
|
|
7
|
-
|
|
8
|
-
def self.attrs_from params
|
|
9
|
-
{ uuid: -> { UUID.new } }.tap do |attrs|
|
|
10
|
-
attrs.merge! params.pop if params.last.is_a? Hash
|
|
11
|
-
attrs.merge! raises_from params
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.class_definition_from attrs
|
|
16
|
-
Class.new do
|
|
17
|
-
define_singleton_method(:attrs) { attrs }
|
|
18
|
-
|
|
19
|
-
def self.from_h hash, repos: Repos
|
|
20
|
-
args = hash.reduce({}) do |result, (key, _)|
|
|
21
|
-
result.merge from_h_mapping hash, key, repos
|
|
22
|
-
end
|
|
23
|
-
new args
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def initialize args = {}
|
|
27
|
-
@values = Hash[self.class.attrs.map do |attr, default|
|
|
28
|
-
value = args.fetch attr do
|
|
29
|
-
default.respond_to?(:call) ? default.call : default
|
|
30
|
-
end
|
|
31
|
-
[attr, value]
|
|
32
|
-
end]
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def == other
|
|
36
|
-
uuid == other.uuid
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
attrs.each do |attr, _|
|
|
40
|
-
define_method(attr) { @values[attr] }
|
|
41
|
-
define_method("#{attr}=") { |val| @values[attr] = val }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def to_h
|
|
45
|
-
self.class.attrs.reduce({}) do |hash, (attr, _)|
|
|
46
|
-
hash.merge to_h_mapping attr
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
|
|
52
|
-
def self.from_h_mapping hash, key, repos
|
|
53
|
-
case key
|
|
54
|
-
when :host, :port, :prot
|
|
55
|
-
{ addr: Addr[hash[:host], hash[:port], hash[:prot].to_sym] }
|
|
56
|
-
when :client_uuid then { client: repos[Client][hash[key]] }
|
|
57
|
-
when :project_uuid then { project: repos[Project][hash[key]] }
|
|
58
|
-
when :task_uuid then { task: repos[Task][hash[key]] }
|
|
59
|
-
else { key => hash[key] }
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def to_h_mapping attr
|
|
64
|
-
case value = @values[attr]
|
|
65
|
-
when Addr
|
|
66
|
-
{ host: value.host, port: value.port, prot: value.prot.to_s }
|
|
67
|
-
when Client then { client_uuid: client.uuid }
|
|
68
|
-
when Project then { project_uuid: project.uuid }
|
|
69
|
-
when Task then { task_uuid: task.uuid }
|
|
70
|
-
else { attr => value }
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def self.raises_from params
|
|
77
|
-
Hash[params.map { |param| [param, -> { raise "#{param} required" }] }]
|
|
78
|
-
end
|
|
79
|
-
end
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
require_relative '../spec_helper'
|
|
2
|
-
|
|
3
|
-
module Kamerling describe '.UUIDObject' do
|
|
4
|
-
describe '.from_h' do
|
|
5
|
-
it 'deserialises the object from a Hash' do
|
|
6
|
-
Trivial = Kamerling.UUIDObject :question
|
|
7
|
-
Trivial.from_h(question: :answer).question.must_equal :answer
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it 'deserialises addr' do
|
|
11
|
-
Netable = Kamerling.UUIDObject :addr
|
|
12
|
-
Netable.from_h(host: '127.0.0.1', port: 1981, prot: :TCP).addr
|
|
13
|
-
.must_equal Addr['127.0.0.1', 1981, :TCP]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'deserialises {client,project,task}_uuid' do
|
|
17
|
-
client = fake :client, uuid: UUID.new
|
|
18
|
-
project = fake :project, uuid: UUID.new
|
|
19
|
-
task = fake :task, uuid: UUID.new
|
|
20
|
-
Complete = Kamerling.UUIDObject :client, :project, :task
|
|
21
|
-
repos = {
|
|
22
|
-
Client => { client.uuid => client },
|
|
23
|
-
Project => { project.uuid => project },
|
|
24
|
-
Task => { task.uuid => task },
|
|
25
|
-
}
|
|
26
|
-
hash = { client_uuid: client.uuid, project_uuid: project.uuid,
|
|
27
|
-
task_uuid: task.uuid, uuid: UUID.new }
|
|
28
|
-
complete = Complete.from_h hash, repos: repos
|
|
29
|
-
complete.client.must_equal client
|
|
30
|
-
complete.project.must_equal project
|
|
31
|
-
complete.task.must_equal task
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe '.new' do
|
|
36
|
-
it 'creates a class with an UUID property defaulting to a random UUID' do
|
|
37
|
-
AttrLess = Kamerling.UUIDObject
|
|
38
|
-
AttrLess.new.uuid.must_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/)
|
|
39
|
-
AttrLess.new.uuid.wont_equal AttrLess.new.uuid
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'allows setting custom properties and raises when they lack defaults' do
|
|
43
|
-
FooFul = Kamerling.UUIDObject :foo
|
|
44
|
-
FooFul.new(foo: 'bar').foo.must_equal 'bar'
|
|
45
|
-
-> { FooFul.new }.must_raise RuntimeError
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'allows setting properties’ default procs' do
|
|
49
|
-
ProcFul = Kamerling.UUIDObject rand: -> { rand }
|
|
50
|
-
ProcFul.new.rand.wont_equal ProcFul.new.rand
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it 'allows setting properties’ default values' do
|
|
54
|
-
ValFul = Kamerling.UUIDObject bar: :baz
|
|
55
|
-
ValFul.new.bar.must_equal :baz
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
describe '#==' do
|
|
60
|
-
it 'reports UUID-based euqality' do
|
|
61
|
-
Actor = Kamerling.UUIDObject :name
|
|
62
|
-
Actor.new(name: :laurel).wont_equal Actor.new name: :laurel
|
|
63
|
-
uuid = UUID.new
|
|
64
|
-
Actor.new(name: :laurel, uuid: uuid)
|
|
65
|
-
.must_equal Actor.new name: :hardy, uuid: uuid
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
describe '#to_h' do
|
|
70
|
-
it 'serialises the object to a Hash' do
|
|
71
|
-
Hashble = Kamerling.UUIDObject :param
|
|
72
|
-
Hashble.new(param: :val).to_h.must_equal param: :val, uuid: anything
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'serialises addr' do
|
|
76
|
-
Addrble = Kamerling.UUIDObject :addr
|
|
77
|
-
addrble = Addrble.new addr: Addr['127.0.0.1', 1981, :TCP]
|
|
78
|
-
addrble.to_h.must_equal host: '127.0.0.1', port: 1981, prot: 'TCP',
|
|
79
|
-
uuid: anything
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it 'serialises client' do
|
|
83
|
-
Clintable = Kamerling.UUIDObject :client
|
|
84
|
-
clintable = Clintable.new client: client = Client.new(addr: fake(:addr))
|
|
85
|
-
clintable.to_h.must_equal client_uuid: client.uuid, uuid: anything
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it 'serialises project' do
|
|
89
|
-
Projable = Kamerling.UUIDObject :project
|
|
90
|
-
projable = Projable.new project: project = Project.new(name: 'name')
|
|
91
|
-
projable.to_h.must_equal project_uuid: project.uuid, uuid: anything
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
it 'serialises task' do
|
|
95
|
-
project = fake :project
|
|
96
|
-
Tskble = Kamerling.UUIDObject :task
|
|
97
|
-
tskble = Tskble.new task: task = Task.new(data: 'data', project: project)
|
|
98
|
-
tskble.to_h.must_equal task_uuid: task.uuid, uuid: anything
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end end
|