kamerling 0.0.2 → 0.0.3
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 -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
|