kamerling 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -13
- data/Gemfile +0 -1
- data/Gemfile.lock +64 -64
- data/README.md +18 -1
- data/Rakefile +5 -3
- data/bin/kamerling +1 -1
- data/config/reek.yml +20 -3
- data/kamerling.gemspec +16 -13
- data/lib/kamerling.rb +2 -28
- data/lib/kamerling/addr.rb +17 -3
- data/lib/kamerling/client.rb +10 -11
- data/lib/kamerling/core_extensions/main.rb +14 -14
- data/lib/kamerling/dispatch.rb +13 -0
- data/lib/kamerling/handler.rb +16 -25
- data/lib/kamerling/http_api.rb +50 -34
- data/lib/kamerling/logging.rb +36 -16
- data/lib/kamerling/mapper.rb +33 -0
- data/lib/kamerling/message.rb +50 -37
- data/lib/kamerling/migrations/2_results_received_at.rb +7 -0
- data/lib/kamerling/migrations/3_dispatches.rb +17 -0
- data/lib/kamerling/migrations/4_registrations_registered_at.rb +7 -0
- data/lib/kamerling/migrations/5_clients_type.rb +7 -0
- data/lib/kamerling/net_dispatcher.rb +12 -7
- data/lib/kamerling/project.rb +7 -3
- data/lib/kamerling/receiver.rb +38 -10
- data/lib/kamerling/registrar.rb +45 -8
- data/lib/kamerling/registration.rb +9 -10
- data/lib/kamerling/repo.rb +33 -26
- data/lib/kamerling/repos.rb +52 -45
- data/lib/kamerling/result.rb +10 -11
- data/lib/kamerling/server/http.rb +28 -21
- data/lib/kamerling/server/sock.rb +32 -24
- data/lib/kamerling/server/tcp.rb +23 -15
- data/lib/kamerling/server/udp.rb +24 -16
- data/lib/kamerling/server_runner.rb +30 -41
- data/lib/kamerling/settings.rb +28 -0
- data/lib/kamerling/task.rb +7 -7
- data/lib/kamerling/task_dispatcher.rb +31 -22
- data/lib/kamerling/uuid.rb +13 -11
- data/lib/kamerling/uuid_entity.rb +23 -9
- data/lib/kamerling/value.rb +13 -0
- data/lib/kamerling/views/clients.slim +3 -1
- data/lib/kamerling/views/project.slim +8 -4
- data/lib/kamerling/views/projects.slim +7 -1
- data/spec/kamerling/addr_spec.rb +32 -22
- data/spec/kamerling/client_spec.rb +9 -5
- data/spec/kamerling/core_extensions/main_spec.rb +18 -13
- data/spec/kamerling/dispatch_spec.rb +16 -0
- data/spec/kamerling/handler_spec.rb +24 -34
- data/spec/kamerling/http_api_spec.rb +94 -73
- data/spec/kamerling/logging_spec.rb +93 -62
- data/spec/kamerling/mapper_spec.rb +151 -0
- data/spec/kamerling/message_spec.rb +73 -49
- data/spec/kamerling/net_dispatcher_spec.rb +22 -16
- data/spec/kamerling/receiver_spec.rb +29 -19
- data/spec/kamerling/registrar_spec.rb +43 -15
- data/spec/kamerling/registration_spec.rb +17 -0
- data/spec/kamerling/repo_spec.rb +63 -47
- data/spec/kamerling/repos_spec.rb +121 -109
- data/spec/kamerling/result_spec.rb +16 -0
- data/spec/kamerling/server/http_spec.rb +19 -14
- data/spec/kamerling/server/tcp_spec.rb +41 -35
- data/spec/kamerling/server/udp_spec.rb +40 -34
- data/spec/kamerling/server_runner_spec.rb +62 -53
- data/spec/kamerling/settings_spec.rb +36 -0
- data/spec/kamerling/task_dispatcher_spec.rb +38 -15
- data/spec/kamerling/task_spec.rb +9 -5
- data/spec/kamerling/uuid_entity_spec.rb +53 -25
- data/spec/kamerling/uuid_spec.rb +19 -16
- data/spec/kamerling/value_spec.rb +21 -0
- data/spec/spec_helper.rb +3 -6
- metadata +54 -8
- data/lib/kamerling/core_extensions.rb +0 -1
data/lib/kamerling/project.rb
CHANGED
data/lib/kamerling/receiver.rb
CHANGED
@@ -1,11 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
require_relative 'client'
|
2
|
+
require_relative 'repos'
|
3
|
+
require_relative 'result'
|
4
|
+
require_relative 'task'
|
5
|
+
|
6
|
+
module Kamerling
|
7
|
+
class Receiver
|
8
|
+
def self.receive(addr:, message:, repos: Repos)
|
9
|
+
new(addr: addr, message: message, repos: repos).receive
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(addr:, message:, repos:)
|
13
|
+
@addr, @message, @repos = addr, message, repos
|
14
|
+
end
|
15
|
+
|
16
|
+
def receive
|
17
|
+
client.busy = false
|
18
|
+
task.done = true
|
19
|
+
repos << result << client << task
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :addr, :message, :repos
|
23
|
+
private :addr, :message, :repos
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def client
|
28
|
+
@client ||= repos[Client][message.client_uuid]
|
29
|
+
end
|
30
|
+
|
31
|
+
def result
|
32
|
+
Result.new(addr: addr, client: client, data: message.payload, task: task)
|
33
|
+
end
|
34
|
+
|
35
|
+
def task
|
36
|
+
@task ||= repos[Task][message.task_uuid]
|
37
|
+
end
|
10
38
|
end
|
11
|
-
end
|
39
|
+
end
|
data/lib/kamerling/registrar.rb
CHANGED
@@ -1,9 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
require_relative 'client'
|
2
|
+
require_relative 'project'
|
3
|
+
require_relative 'registration'
|
4
|
+
require_relative 'repos'
|
5
|
+
require_relative 'uuid'
|
6
|
+
|
7
|
+
module Kamerling
|
8
|
+
class Registrar
|
9
|
+
def self.register(addr:, message:, repos: Repos)
|
10
|
+
new(addr: addr, message: message, repos: repos).register
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(addr:, message:, repos:)
|
14
|
+
@addr, @message, @repos = addr, message, repos
|
15
|
+
end
|
16
|
+
|
17
|
+
def register
|
18
|
+
client.addr = addr
|
19
|
+
repos << client
|
20
|
+
repos << registration
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :addr, :message, :repos
|
24
|
+
private :addr, :message, :repos
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def client
|
29
|
+
@client ||= find_or_create_client
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_or_create_client
|
33
|
+
repos[Client][message.client_uuid]
|
34
|
+
rescue Repo::NotFound
|
35
|
+
Client.new(addr: addr, uuid: message.client_uuid)
|
36
|
+
end
|
37
|
+
|
38
|
+
def project
|
39
|
+
@project ||= repos[Project][message.project_uuid]
|
40
|
+
end
|
41
|
+
|
42
|
+
def registration
|
43
|
+
Registration.new(addr: addr, client: client, project: project)
|
44
|
+
end
|
8
45
|
end
|
9
|
-
end
|
46
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require_relative 'addr'
|
2
|
+
require_relative 'client'
|
3
|
+
require_relative 'project'
|
4
|
+
require_relative 'uuid_entity'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
.reject { |key, _| key == :project }.merge project_uuid: project.uuid
|
6
|
+
module Kamerling
|
7
|
+
class Registration < UUIDEntity
|
8
|
+
attrs addr: Addr, client: Client, project: Project, registered_at: Time
|
9
|
+
defaults registered_at: -> (*) { Time.now }
|
11
10
|
end
|
12
|
-
end
|
11
|
+
end
|
data/lib/kamerling/repo.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'sequel'
|
2
|
+
require_relative 'mapper'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Kamerling
|
5
|
+
class Repo
|
6
|
+
NotFound = Class.new(RuntimeError)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
8
|
+
def initialize(klass, source, mapper: Mapper)
|
9
|
+
@klass = klass
|
10
|
+
@mapper = mapper
|
11
|
+
@source = source
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
def <<(object)
|
15
|
+
hash = mapper.to_h(object)
|
16
|
+
warn_off { source << hash }
|
17
|
+
rescue Sequel::UniqueConstraintViolation
|
18
|
+
warn_off { source.where(uuid: object.uuid).update hash }
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def [](uuid)
|
22
|
+
hash = warn_off { source[uuid: uuid] }
|
23
|
+
fail NotFound, "#{klass} with UUID #{uuid}" unless hash
|
24
|
+
mapper.from_h(klass, hash)
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def all
|
28
|
+
source.all.map { |hash| mapper.from_h(klass, hash) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def related_to(object)
|
32
|
+
key = "#{object.class.name.split('::').last.downcase}_uuid".to_sym
|
33
|
+
source.where(key => object.uuid).map { |hash| mapper.from_h(klass, hash) }
|
34
|
+
end
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
end
|
36
|
+
attr_reader :klass, :mapper, :source
|
37
|
+
private :klass, :mapper, :source
|
38
|
+
end
|
39
|
+
end
|
data/lib/kamerling/repos.rb
CHANGED
@@ -1,65 +1,72 @@
|
|
1
1
|
warn_off { require 'sequel' }
|
2
|
+
require_relative 'client'
|
3
|
+
require_relative 'project'
|
4
|
+
require_relative 'registration'
|
5
|
+
require_relative 'repo'
|
6
|
+
require_relative 'task'
|
2
7
|
|
3
8
|
Sequel.extension :migration
|
4
9
|
|
5
|
-
module Kamerling
|
6
|
-
class
|
7
|
-
|
10
|
+
module Kamerling
|
11
|
+
class Repos
|
12
|
+
class << self
|
13
|
+
attr_writer :repos
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
def <<(object)
|
16
|
+
repos[object.class] << object
|
17
|
+
self
|
18
|
+
end
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
20
|
+
def [](klass)
|
21
|
+
repos[klass]
|
22
|
+
end
|
17
23
|
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
def clients
|
25
|
+
repos[Client].all
|
26
|
+
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
def clients_for(project)
|
29
|
+
repos[Registration].related_to(project).map(&:client)
|
30
|
+
end
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
def db=(db)
|
33
|
+
warn_off { Sequel::Migrator.run db, "#{__dir__}/migrations" }
|
34
|
+
@repos = nil
|
35
|
+
@db = db
|
36
|
+
end
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
def free_clients_for(project)
|
39
|
+
clients_for(project).reject(&:busy)
|
40
|
+
end
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
def next_task_for(project)
|
43
|
+
repos[Task].related_to(project).reject(&:done).first
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
def project(project_uuid)
|
47
|
+
repos[Project][project_uuid]
|
48
|
+
end
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
|
50
|
+
def projects
|
51
|
+
repos[Project].all
|
52
|
+
end
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
def tasks_for(project)
|
55
|
+
repos[Task].related_to(project)
|
56
|
+
end
|
51
57
|
|
52
|
-
|
58
|
+
private
|
53
59
|
|
54
|
-
|
55
|
-
|
56
|
-
|
60
|
+
def db
|
61
|
+
@db ||= self.db = Sequel.sqlite
|
62
|
+
end
|
57
63
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
def repos
|
65
|
+
@repos ||= Hash.new do |repos, klass|
|
66
|
+
table = "#{klass.name.split('::').last.downcase}s".to_sym
|
67
|
+
repos[klass] = Repo.new(klass, warn_off { db[table] })
|
68
|
+
end
|
62
69
|
end
|
63
70
|
end
|
64
71
|
end
|
65
|
-
end
|
72
|
+
end
|
data/lib/kamerling/result.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
attribute :task, Task
|
1
|
+
require_relative 'addr'
|
2
|
+
require_relative 'client'
|
3
|
+
require_relative 'task'
|
4
|
+
require_relative 'uuid_entity'
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
module Kamerling
|
7
|
+
class Result < UUIDEntity
|
8
|
+
attrs addr: Addr, client: Client, data: String, received_at: Time,
|
9
|
+
task: Task
|
10
|
+
defaults received_at: -> (*) { Time.now }
|
12
11
|
end
|
13
|
-
end
|
12
|
+
end
|
@@ -1,26 +1,33 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'rack'
|
2
|
+
require_relative '../http_api'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Kamerling
|
5
|
+
module Server
|
6
|
+
class HTTP
|
7
|
+
attr_reader :addr
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def initialize(addr:)
|
10
|
+
@addr = addr
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
loop { break if addr.connectable? }
|
17
|
-
self
|
18
|
-
end
|
13
|
+
def join
|
14
|
+
thread.join
|
15
|
+
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
def start
|
18
|
+
@thread = Thread.new do
|
19
|
+
Rack::Handler::WEBrick.run HTTPAPI, Host: addr.host, Port: addr.port
|
20
|
+
end
|
21
|
+
loop { break if addr.connectable? }
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop
|
26
|
+
thread.exit.join
|
27
|
+
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
29
|
+
attr_reader :thread
|
30
|
+
private :thread
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,32 +1,40 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../handler'
|
2
|
+
require_relative '../message'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Kamerling
|
5
|
+
module Server
|
6
|
+
class Sock
|
7
|
+
attr_reader :addr
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def initialize(addr:, handler: Handler.new)
|
10
|
+
@addr = addr
|
11
|
+
@handler = handler
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
self
|
17
|
-
end
|
14
|
+
def join
|
15
|
+
thread.join
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
def start
|
19
|
+
@thread = Thread.new { run_loop }
|
20
|
+
wait_till_started
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop
|
25
|
+
thread.exit.join
|
26
|
+
end
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
attr_reader :handler, :thread
|
29
|
+
private :handler, :thread
|
25
30
|
|
26
|
-
|
31
|
+
private
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
33
|
+
def handle(input, client_addr)
|
34
|
+
handler.handle Message.parse(input), client_addr
|
35
|
+
rescue Message::UnknownType
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
31
39
|
end
|
32
|
-
end
|
40
|
+
end
|