cuboid 0.0.5 → 0.1.0

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.
Files changed (217) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +13 -13
  4. data/lib/cuboid/application.rb +10 -10
  5. data/lib/cuboid/option_groups/{dispatcher.rb → agent.rb} +9 -9
  6. data/lib/cuboid/option_groups/paths.rb +1 -1
  7. data/lib/cuboid/options.rb +1 -1
  8. data/lib/cuboid/processes/{dispatchers.rb → agents.rb} +25 -25
  9. data/lib/cuboid/processes/executables/agent.rb +5 -0
  10. data/lib/cuboid/processes/helpers/agents.rb +23 -0
  11. data/lib/cuboid/processes/helpers/instances.rb +4 -4
  12. data/lib/cuboid/processes/helpers.rb +1 -1
  13. data/lib/cuboid/processes/instances.rb +9 -9
  14. data/lib/cuboid/processes/schedulers.rb +2 -2
  15. data/lib/cuboid/processes.rb +2 -2
  16. data/lib/cuboid/rest/server/instance_helpers.rb +13 -13
  17. data/lib/cuboid/rest/server/routes/dispatcher.rb +11 -11
  18. data/lib/cuboid/rest/server/routes/grid.rb +8 -8
  19. data/lib/cuboid/rest/server/routes/instances.rb +1 -1
  20. data/lib/cuboid/rest/server.rb +5 -5
  21. data/lib/cuboid/rpc/client/{dispatcher.rb → agent.rb} +4 -4
  22. data/lib/cuboid/rpc/client/instance.rb +2 -2
  23. data/lib/cuboid/rpc/client.rb +1 -1
  24. data/lib/cuboid/rpc/server/agent/node.rb +247 -0
  25. data/lib/cuboid/rpc/server/{dispatcher → agent}/service.rb +13 -13
  26. data/lib/cuboid/rpc/server/{dispatcher.rb → agent.rb} +32 -31
  27. data/lib/cuboid/rpc/server/application_wrapper.rb +1 -1
  28. data/lib/cuboid/rpc/server/instance.rb +4 -4
  29. data/lib/cuboid/rpc/server/scheduler.rb +12 -12
  30. data/lib/version +1 -1
  31. data/spec/cuboid/option_groups/dispatcher_spec.rb +2 -2
  32. data/spec/cuboid/rest/server_spec.rb +45 -45
  33. data/spec/cuboid/rpc/client/dispatcher_spec.rb +2 -2
  34. data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +65 -65
  35. data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +16 -16
  36. data/spec/cuboid/rpc/server/dispatcher_spec.rb +95 -95
  37. data/spec/cuboid/rpc/server/scheduler_spec.rb +8 -8
  38. data/spec/support/fixtures/executables/node.rb +3 -3
  39. data/spec/support/fixtures/mock_app/test_service.rb +8 -8
  40. data/spec/support/fixtures/mock_app.rb +1 -1
  41. data/spec/support/fixtures/services/echo.rb +6 -6
  42. data/spec/support/helpers/resets.rb +1 -1
  43. data/spec/support/lib/web_server_client.rb +2 -2
  44. data/spec/support/lib/web_server_dispatcher.rb +1 -1
  45. metadata +10 -348
  46. data/lib/cuboid/processes/executables/dispatcher.rb +0 -5
  47. data/lib/cuboid/processes/helpers/dispatchers.rb +0 -23
  48. data/lib/cuboid/rpc/server/dispatcher/node.rb +0 -247
  49. data/spec/support/logs/Dispatcher - 1520492-37227.log +0 -6
  50. data/spec/support/logs/Dispatcher - 1520680-13689.log +0 -6
  51. data/spec/support/logs/Dispatcher - 1520682-24167.log +0 -6
  52. data/spec/support/logs/Dispatcher - 1520688-42731.log +0 -6
  53. data/spec/support/logs/Dispatcher - 1520690-5750.log +0 -10
  54. data/spec/support/logs/Dispatcher - 1520692-55183.log +0 -10
  55. data/spec/support/logs/Dispatcher - 1520695-39752.log +0 -10
  56. data/spec/support/logs/Dispatcher - 1520697-44327.log +0 -10
  57. data/spec/support/logs/Dispatcher - 1520699-58785.log +0 -10
  58. data/spec/support/logs/Dispatcher - 1520701-60952.log +0 -10
  59. data/spec/support/logs/Dispatcher - 1520796-50420.log +0 -6
  60. data/spec/support/logs/Dispatcher - 1520894-56883.log +0 -6
  61. data/spec/support/logs/Dispatcher - 1520896-21419.log +0 -6
  62. data/spec/support/logs/Dispatcher - 1520898-62584.log +0 -6
  63. data/spec/support/logs/Dispatcher - 1520900-59721.log +0 -6
  64. data/spec/support/logs/Dispatcher - 1520910-51632.log +0 -6
  65. data/spec/support/logs/Dispatcher - 1520920-21801.log +0 -6
  66. data/spec/support/logs/Dispatcher - 1520930-49223.log +0 -6
  67. data/spec/support/logs/Dispatcher - 1520933-34241.log +0 -6
  68. data/spec/support/logs/Dispatcher - 1520935-64571.log +0 -6
  69. data/spec/support/logs/Dispatcher - 1520937-50734.log +0 -6
  70. data/spec/support/logs/Dispatcher - 1520939-60841.log +0 -6
  71. data/spec/support/logs/Dispatcher - 1520944-8124.log +0 -6
  72. data/spec/support/logs/Dispatcher - 1520946-25192.log +0 -16
  73. data/spec/support/logs/Dispatcher - 1520948-9752.log +0 -14
  74. data/spec/support/logs/Dispatcher - 1520952-45543.log +0 -10
  75. data/spec/support/logs/Dispatcher - 1520958-36653.log +0 -16
  76. data/spec/support/logs/Dispatcher - 1520960-17456.log +0 -14
  77. data/spec/support/logs/Dispatcher - 1520964-5774.log +0 -10
  78. data/spec/support/logs/Dispatcher - 1520976-40848.log +0 -16
  79. data/spec/support/logs/Dispatcher - 1520978-29867.log +0 -14
  80. data/spec/support/logs/Dispatcher - 1520982-17715.log +0 -10
  81. data/spec/support/logs/Dispatcher - 1520987-8925.log +0 -16
  82. data/spec/support/logs/Dispatcher - 1520989-25480.log +0 -14
  83. data/spec/support/logs/Dispatcher - 1520993-5124.log +0 -10
  84. data/spec/support/logs/Dispatcher - 1520999-12901.log +0 -16
  85. data/spec/support/logs/Dispatcher - 1521004-32265.log +0 -14
  86. data/spec/support/logs/Dispatcher - 1521008-33455.log +0 -10
  87. data/spec/support/logs/Dispatcher - 1521014-13779.log +0 -6
  88. data/spec/support/logs/Dispatcher - 1521017-14755.log +0 -6
  89. data/spec/support/logs/Dispatcher - 1521022-48687.log +0 -6
  90. data/spec/support/logs/Dispatcher - 1521024-59097.log +0 -6
  91. data/spec/support/logs/Dispatcher - 1521034-12604.log +0 -6
  92. data/spec/support/logs/Dispatcher - 1521038-64272.log +0 -6
  93. data/spec/support/logs/Dispatcher - 1521043-8680.log +0 -6
  94. data/spec/support/logs/Dispatcher - 1521047-22949.log +0 -6
  95. data/spec/support/logs/Dispatcher - 1521051-3355.log +0 -6
  96. data/spec/support/logs/Dispatcher - 1521074-12332.log +0 -6
  97. data/spec/support/logs/Dispatcher - 1521118-53130.log +0 -16
  98. data/spec/support/logs/Dispatcher - 1521128-47137.log +0 -14
  99. data/spec/support/logs/Dispatcher - 1521136-30328.log +0 -10
  100. data/spec/support/logs/Dispatcher - 1521161-21329.log +0 -16
  101. data/spec/support/logs/Dispatcher - 1521172-19183.log +0 -14
  102. data/spec/support/logs/Dispatcher - 1521179-34902.log +0 -10
  103. data/spec/support/logs/Dispatcher - 1521190-20155.log +0 -16
  104. data/spec/support/logs/Dispatcher - 1521204-43843.log +0 -14
  105. data/spec/support/logs/Dispatcher - 1521211-23972.log +0 -10
  106. data/spec/support/logs/Dispatcher - 1521237-20879.log +0 -10
  107. data/spec/support/logs/Dispatcher - 1521239-61999.log +0 -10
  108. data/spec/support/logs/Dispatcher - 1521242-20975.log +0 -16
  109. data/spec/support/logs/Dispatcher - 1521246-28409.log +0 -14
  110. data/spec/support/logs/Dispatcher - 1521250-58505.log +0 -10
  111. data/spec/support/logs/Dispatcher - 1521262-53292.log +0 -6
  112. data/spec/support/logs/Dispatcher - 1521266-42758.log +0 -6
  113. data/spec/support/logs/Dispatcher - 1521277-4215.log +0 -6
  114. data/spec/support/logs/Dispatcher - 1521292-16086.log +0 -6
  115. data/spec/support/logs/Dispatcher - 1521301-42112.log +0 -6
  116. data/spec/support/logs/Dispatcher - 1521312-61196.log +0 -6
  117. data/spec/support/logs/Dispatcher - 1521316-23353.log +0 -6
  118. data/spec/support/logs/Dispatcher - 1521321-46361.log +0 -6
  119. data/spec/support/logs/Dispatcher - 1521438-46016.log +0 -6
  120. data/spec/support/logs/Dispatcher - 1521454-49862.log +0 -6
  121. data/spec/support/logs/Dispatcher - 1521470-54737.log +0 -6
  122. data/spec/support/logs/Instance - 1521353-26273.error.log +0 -105
  123. data/spec/support/logs/Instance - 1521355-56591.error.log +0 -105
  124. data/spec/support/logs/Instance - 1521363-26218.error.log +0 -105
  125. data/spec/support/logs/Scheduler - 1520469-35703.log +0 -3
  126. data/spec/support/logs/Scheduler - 1520473-60524.log +0 -6
  127. data/spec/support/logs/Scheduler - 1520509-34951.log +0 -3
  128. data/spec/support/logs/Scheduler - 1520517-31455.log +0 -6
  129. data/spec/support/logs/Scheduler - 1520529-43808.log +0 -4
  130. data/spec/support/logs/Scheduler - 1520536-23387.log +0 -1
  131. data/spec/support/logs/Scheduler - 1520549-48260.log +0 -3
  132. data/spec/support/logs/Scheduler - 1520563-45636.log +0 -6
  133. data/spec/support/logs/Scheduler - 1520599-40643.log +0 -3
  134. data/spec/support/logs/Scheduler - 1520608-54106.log +0 -6
  135. data/spec/support/logs/Scheduler - 1520629-24722.log +0 -3
  136. data/spec/support/logs/Scheduler - 1520637-61755.log +0 -6
  137. data/spec/support/logs/Scheduler - 1520663-17447.log +0 -4
  138. data/spec/support/logs/Scheduler - 1520671-38282.log +0 -6
  139. data/spec/support/logs/Scheduler - 1520703-33082.log +0 -1
  140. data/spec/support/logs/Scheduler - 1520706-22309.log +0 -1
  141. data/spec/support/logs/Scheduler - 1520709-1816.log +0 -1
  142. data/spec/support/logs/Scheduler - 1520711-19998.log +0 -1
  143. data/spec/support/logs/Scheduler - 1520714-47570.log +0 -1
  144. data/spec/support/logs/Scheduler - 1520723-18521.log +0 -1
  145. data/spec/support/logs/Scheduler - 1520725-40913.log +0 -3
  146. data/spec/support/logs/Scheduler - 1520749-45742.log +0 -6
  147. data/spec/support/logs/Scheduler - 1520759-44350.log +0 -4
  148. data/spec/support/logs/Scheduler - 1520770-53219.log +0 -1
  149. data/spec/support/logs/Scheduler - 1520773-54792.log +0 -1
  150. data/spec/support/logs/Scheduler - 1520777-19636.log +0 -1
  151. data/spec/support/logs/Scheduler - 1520780-51801.log +0 -1
  152. data/spec/support/logs/Scheduler - 1520782-9652.log +0 -3
  153. data/spec/support/logs/Scheduler - 1520786-59472.log +0 -1
  154. data/spec/support/logs/Scheduler - 1520789-1603.log +0 -1
  155. data/spec/support/logs/Scheduler - 1520792-35476.log +0 -1
  156. data/spec/support/logs/Scheduler - 1521410-47324.log +0 -16
  157. data/spec/support/logs/Scheduler - 1521422-33737.log +0 -6
  158. data/spec/support/logs/Scheduler - 1521433-36637.log +0 -6
  159. data/spec/support/logs/Scheduler - 1521440-15066.log +0 -6
  160. data/spec/support/logs/Scheduler - 1521456-48637.log +0 -3
  161. data/spec/support/logs/Scheduler - 1521472-54425.log +0 -5
  162. data/spec/support/logs/Scheduler - 1521496-12923.log +0 -1
  163. data/spec/support/logs/Scheduler - 1521518-46819.log +0 -1
  164. data/spec/support/logs/Scheduler - 1521522-21417.log +0 -1
  165. data/spec/support/logs/Scheduler - 1521525-35088.log +0 -1
  166. data/spec/support/logs/Scheduler - 1521528-13676.log +0 -1
  167. data/spec/support/logs/Scheduler - 1521530-48176.log +0 -1
  168. data/spec/support/logs/Scheduler - 1521532-13207.log +0 -1
  169. data/spec/support/logs/Scheduler - 1521535-5799.log +0 -3
  170. data/spec/support/logs/Scheduler - 1521543-62784.log +0 -3
  171. data/spec/support/logs/Scheduler - 1521551-10263.log +0 -3
  172. data/spec/support/logs/Scheduler - 1521556-56026.log +0 -3
  173. data/spec/support/logs/Scheduler - 1521560-14551.log +0 -4
  174. data/spec/support/logs/Scheduler - 1521573-47584.log +0 -1
  175. data/spec/support/logs/Scheduler - 1521578-14443.log +0 -4
  176. data/spec/support/logs/Scheduler - 1521580-60337.log +0 -1
  177. data/spec/support/logs/Scheduler - 1521583-52039.log +0 -1
  178. data/spec/support/logs/Scheduler - 1521586-1500.log +0 -16
  179. data/spec/support/logs/Scheduler - 1521598-61298.log +0 -4
  180. data/spec/support/logs/Scheduler - 1521602-61490.log +0 -1
  181. data/spec/support/logs/Scheduler - 1521604-29209.log +0 -1
  182. data/spec/support/logs/Scheduler - 1521606-47734.log +0 -1
  183. data/spec/support/logs/Scheduler - 1521612-63269.log +0 -1
  184. data/spec/support/logs/Scheduler - 1521614-47018.log +0 -3
  185. data/spec/support/logs/Scheduler - 1521619-32411.log +0 -1
  186. data/spec/support/logs/Scheduler - 1521621-42861.log +0 -1
  187. data/spec/support/logs/Scheduler - 1521623-56258.log +0 -1
  188. data/spec/support/logs/Scheduler - 1521627-9487.log +0 -1
  189. data/spec/support/logs/Scheduler - 1521630-3345.log +0 -1
  190. data/spec/support/logs/Scheduler - 1521632-47325.log +0 -1
  191. data/spec/support/logs/Scheduler - 1521635-22156.log +0 -2
  192. data/spec/support/logs/error-1520329.log +0 -797
  193. data/spec/support/logs/output_spec_1520329.log +0 -390
  194. data/spec/support/reports/003bed585153336c2548d1c60a026a3e.crf +0 -0
  195. data/spec/support/reports/30e3c7a8c13e9b40a0a443a5e5a4ff94.crf +0 -0
  196. data/spec/support/reports/31655751a9f0eee91e588bc796985b1e.crf +0 -0
  197. data/spec/support/reports/40801b7993c0ed919b73242a9c078dde.crf +0 -0
  198. data/spec/support/reports/4719b89667e92bb80102f4b0bb4c0c75.crf +0 -0
  199. data/spec/support/reports/4e765a3d2870d2763ea72167bd3db9d6.crf +0 -0
  200. data/spec/support/reports/61968f732d8ae715c104175e43679915.crf +0 -0
  201. data/spec/support/reports/63446a8ec637d9991b8c6a1151ae59a9.crf +0 -0
  202. data/spec/support/reports/737144b18305c7a115ad7964b9bbe41c.crf +0 -0
  203. data/spec/support/reports/73fe5f7adf905045c3fe4669bdf60d02.crf +0 -0
  204. data/spec/support/reports/86cd396db9ef97472876f32e57c44ce7.crf +0 -0
  205. data/spec/support/reports/8a031ac2b2730dfd07a1d1ca870299f2.crf +0 -0
  206. data/spec/support/reports/8e16ac74484ee5d8cf7073fe22adf787.crf +0 -0
  207. data/spec/support/reports/8eff857213ab6ff712a0b0e8582855c9.crf +0 -0
  208. data/spec/support/reports/9e0e6ed8718973b3d4e63bbb7dd1d1c6.crf +0 -0
  209. data/spec/support/reports/a9c88f967d09cb9c4e8e1180cfb24828.crf +0 -0
  210. data/spec/support/reports/ba32970a64686e45ec8caa5032f65c2e.crf +0 -0
  211. data/spec/support/reports/cceb7596659fd619ab4438953cbda78b.crf +0 -0
  212. data/spec/support/reports/d2e0f4558b605ffd1215e9226815b951.crf +0 -0
  213. data/spec/support/snapshots/Cuboid 2022-01-24 14_38_16 +0200 8238609e31cedaf1bcb89205f9d42121.csf +0 -0
  214. data/spec/support/snapshots/Cuboid 2022-01-24 14_38_30 +0200 68690b002e79c7bc9e3aabfcbc7ac5a7.csf +0 -0
  215. data/spec/support/snapshots/Cuboid 2022-01-24 14_46_39 +0200 6fd3c9491d3e784e18f9c3c0d9deddec.csf +0 -0
  216. data/spec/support/snapshots/Cuboid 2022-01-24 14_46_44 +0200 c3a012fba59210bc7c169afb0565d5a8.csf +0 -0
  217. data/spec/support/snapshots/Cuboid 2022-01-24 14_46_46 +0200 e4c1ce35d8e62e6a16f84eccd36b2283.csf +0 -0
@@ -5,10 +5,10 @@ require Options.paths.lib + 'rpc/client/base'
5
5
  module RPC
6
6
  class Client
7
7
 
8
- # RPC Dispatcher client
8
+ # RPC Agent client
9
9
  #
10
10
  # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
11
- class Dispatcher
11
+ class Agent
12
12
  # Not always available, set by the parent.
13
13
  attr_accessor :pid
14
14
 
@@ -18,7 +18,7 @@ class Dispatcher
18
18
  @client = Base.new( url, nil, options )
19
19
  @node = Arachni::RPC::Proxy.new( @client, 'node' )
20
20
 
21
- Cuboid::Application.application.dispatcher_services.keys.each do |name|
21
+ Cuboid::Application.application.agent_services.keys.each do |name|
22
22
  self.class.send( :attr_reader, name.to_sym )
23
23
 
24
24
  instance_variable_set(
@@ -48,7 +48,7 @@ class Dispatcher
48
48
 
49
49
  # Used to provide the illusion of locality for remote methods
50
50
  def method_missing( sym, *args, &block )
51
- @client.call( "dispatcher.#{sym.to_s}", *args, &block )
51
+ @client.call( "agent.#{sym.to_s}", *args, &block )
52
52
  end
53
53
 
54
54
  end
@@ -5,7 +5,7 @@ require Options.paths.lib + 'rpc/client/base'
5
5
  module RPC
6
6
  class Client
7
7
 
8
- # RPC client for remote instances spawned by a remote dispatcher
8
+ # RPC client for remote instances spawned by a remote agent
9
9
  #
10
10
  # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
11
11
  class Instance
@@ -47,7 +47,7 @@ class Instance
47
47
  @instance = Proxy.new( @client )
48
48
  @options = Arachni::RPC::Proxy.new( @client, 'options' )
49
49
 
50
- # map Dispatcher handlers
50
+ # map Agent handlers
51
51
  Cuboid::Application.application.instance_services.keys.each do |name|
52
52
  self.class.send( :attr_reader, name.to_sym )
53
53
 
@@ -1,3 +1,3 @@
1
1
  require_relative 'client/instance'
2
- require_relative 'client/dispatcher'
2
+ require_relative 'client/agent'
3
3
  require_relative 'client/scheduler'
@@ -0,0 +1,247 @@
1
+ module Cuboid
2
+
3
+ require Options.paths.lib + 'rpc/server/output'
4
+
5
+ module RPC
6
+
7
+ # Agent node class, helps maintain a list of all available Agents in
8
+ # the grid and announce itself to peering Agents.
9
+ #
10
+ # As soon as a new Node is fired up it checks-in with its peer and grabs
11
+ # a list of all available peers.
12
+ #
13
+ # As soon as it receives the peer list it then announces itself to them.
14
+ #
15
+ # Upon convergence there will be a grid of Agents each one with its own
16
+ # copy of all available Agent URLs.
17
+ #
18
+ # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
19
+ class Server::Agent::Node
20
+ include UI::Output
21
+
22
+ # Initializes the node by:
23
+ #
24
+ # * Adding the peer (if the user has supplied one) to the peer list.
25
+ # * Getting the peer's peer list and appending them to its own.
26
+ # * Announces itself to the peer and instructs it to propagate our URL
27
+ # to the others.
28
+ #
29
+ # @param [Cuboid::Options] options
30
+ # @param [Server::Base] server
31
+ # Agent's RPC server.
32
+ # @param [String] logfile
33
+ # Where to send the output.
34
+ def initialize( options, server, logfile = nil )
35
+ @options = options
36
+ @server = server
37
+ @url = @server.url
38
+
39
+ reroute_to_file( logfile ) if logfile
40
+
41
+ print_status 'Initializing grid node...'
42
+
43
+ @dead_nodes = Set.new
44
+ @peers = Set.new
45
+ @nodes_info_cache = []
46
+
47
+ if (peer = @options.agent.peer)
48
+ # Grab the peer's peers.
49
+ connect_to_peer( peer ).peers do |urls|
50
+ if urls.rpc_exception?
51
+ add_dead_peer( peer )
52
+ print_info "Neighbour seems dead: #{peer}"
53
+ add_dead_peer( peer )
54
+ next
55
+ end
56
+
57
+ # Add peer and announce it to everyone.
58
+ add_peer( peer, true )
59
+
60
+ urls.each { |url| @peers << url if url != @url }
61
+ end
62
+ end
63
+
64
+ print_status 'Node ready.'
65
+
66
+ log_updated_peers
67
+
68
+ Arachni::Reactor.global.at_interval( @options.agent.ping_interval ) do
69
+ ping
70
+ check_for_comebacks
71
+ end
72
+ end
73
+
74
+ # @return [Boolean]
75
+ # `true` if grid member, `false` otherwise.
76
+ def grid_member?
77
+ @peers.any?
78
+ end
79
+
80
+ def unplug
81
+ @peers.each do |peer|
82
+ connect_to_peer( peer ).remove_peer( @url ) {}
83
+ end
84
+
85
+ @peers.clear
86
+ @dead_nodes.clear
87
+
88
+ nil
89
+ end
90
+
91
+ # Adds a peer to the peer list.
92
+ #
93
+ # @param [String] node_url
94
+ # URL of a peering node.
95
+ # @param [Boolean] propagate
96
+ # Whether or not to announce the new node to the peers.
97
+ def add_peer( node_url, propagate = false )
98
+ # we don't want ourselves in the Set
99
+ return false if node_url == @url
100
+ return false if @peers.include?( node_url )
101
+
102
+ print_status "Adding peer: #{node_url}"
103
+
104
+ @peers << node_url
105
+ log_updated_peers
106
+ announce( node_url ) if propagate
107
+
108
+ connect_to_peer( node_url ).add_peer( @url, propagate ) do |res|
109
+ next if !res.rpc_exception?
110
+ add_dead_peer( node_url )
111
+ print_status "Neighbour seems dead: #{node_url}"
112
+ end
113
+ true
114
+ end
115
+
116
+ def remove_peer( url )
117
+ @peers.delete url
118
+ @dead_nodes.delete url
119
+ nil
120
+ end
121
+
122
+ # @return [Array]
123
+ # Neighbour/node/peer URLs.
124
+ def peers
125
+ @peers.to_a
126
+ end
127
+
128
+ def peers_with_info( &block )
129
+ fail 'This method requires a block!' if !block_given?
130
+
131
+ @peers_cmp = ''
132
+
133
+ if @nodes_info_cache.empty? || @peers_cmp != peers.to_s
134
+ @peers_cmp = peers.to_s
135
+
136
+ each = proc do |peer, iter|
137
+ connect_to_peer( peer ).info do |info|
138
+ if info.rpc_exception?
139
+ print_info "Neighbour seems dead: #{peer}"
140
+ add_dead_peer( peer )
141
+ log_updated_peers
142
+
143
+ iter.return( nil )
144
+ else
145
+ iter.return( info )
146
+ end
147
+ end
148
+ end
149
+
150
+ after = proc do |nodes|
151
+ @nodes_info_cache = nodes.compact
152
+ block.call( @nodes_info_cache )
153
+ end
154
+
155
+ Arachni::Reactor.global.create_iterator( peers ).map( each, after )
156
+ else
157
+ block.call( @nodes_info_cache )
158
+ end
159
+ end
160
+
161
+ # @return [Hash]
162
+ #
163
+ # * `url` -- This node's URL.
164
+ # * `name` -- Nickname
165
+ # * `peers` -- Array of peers.
166
+ def info
167
+ {
168
+ 'url' => @url,
169
+ 'name' => @options.agent.name,
170
+ 'peers' => @peers.to_a,
171
+ 'unreachable_peers' => @dead_nodes.to_a
172
+ }
173
+ end
174
+
175
+ def alive?
176
+ true
177
+ end
178
+
179
+ private
180
+
181
+ def add_dead_peer( url )
182
+ remove_peer( url )
183
+ @dead_nodes << url
184
+ end
185
+
186
+ def log_updated_peers
187
+ print_info 'Updated peers:'
188
+
189
+ if !peers.empty?
190
+ peers.each { |node| print_info( '---- ' + node ) }
191
+ else
192
+ print_info '<empty>'
193
+ end
194
+ end
195
+
196
+ def ping
197
+ peers.each do |peer|
198
+ connect_to_peer( peer ).alive? do |res|
199
+ next if !res.rpc_exception?
200
+ add_dead_peer( peer )
201
+ print_status "Found dead peer: #{peer} "
202
+ end
203
+ end
204
+ end
205
+
206
+ def check_for_comebacks
207
+ @dead_nodes.dup.each do |url|
208
+ peer = connect_to_peer( url )
209
+ peer.alive? do |res|
210
+ next if res.rpc_exception?
211
+
212
+ print_status "Agent came back to life: #{url}"
213
+ ([@url] | peers).each do |node|
214
+ peer.add_peer( node ){}
215
+ end
216
+
217
+ add_peer( url )
218
+ @dead_nodes.delete url
219
+ end
220
+ end
221
+ end
222
+
223
+ # Announces the node to the ones in the peer list
224
+ #
225
+ # @param [String] node
226
+ # URL
227
+ def announce( node )
228
+ print_status "Advertising: #{node}"
229
+
230
+ peers.each do |peer|
231
+ next if peer == node
232
+
233
+ print_info '---- to: ' + peer
234
+ connect_to_peer( peer ).add_peer( node ) do |res|
235
+ add_dead_peer( peer ) if res.rpc_exception?
236
+ end
237
+ end
238
+ end
239
+
240
+ def connect_to_peer( url )
241
+ @rpc_clients ||= {}
242
+ @rpc_clients[url] ||= Client::Agent.new( url ).node
243
+ end
244
+
245
+ end
246
+ end
247
+ end
@@ -1,7 +1,7 @@
1
1
  module Cuboid
2
2
  module RPC
3
3
 
4
- # Base class and namespace for all Dispatcher services.
4
+ # Base class and namespace for all Agent services.
5
5
  #
6
6
  # # RPC accessibility
7
7
  #
@@ -26,20 +26,20 @@ module RPC
26
26
  # results to that block instead of returning a value.
27
27
  #
28
28
  # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
29
- class Server::Dispatcher::Service
29
+ class Server::Agent::Service
30
30
 
31
31
  attr_reader :options
32
- attr_reader :dispatcher
32
+ attr_reader :agent
33
33
 
34
- def initialize( options, dispatcher )
34
+ def initialize( options, agent )
35
35
  @options = options
36
- @dispatcher = dispatcher
36
+ @agent = agent
37
37
  end
38
38
 
39
- # @return [Server::Dispatcher::Node]
39
+ # @return [Server::Agent::Node]
40
40
  # Local node.
41
41
  def node
42
- dispatcher.instance_eval { @node }
42
+ agent.instance_eval { @node }
43
43
  end
44
44
 
45
45
  # Performs an asynchronous map operation over all running instances.
@@ -102,17 +102,17 @@ class Server::Dispatcher::Service
102
102
  # @return [Array<Hash>]
103
103
  # Alive instances.
104
104
  def instances
105
- dispatcher.running_instances
105
+ agent.running_instances
106
106
  end
107
107
 
108
- # Connects to a Dispatcher by `url`
108
+ # Connects to a Agent by `url`
109
109
  #
110
110
  # @param [String] url
111
111
  #
112
- # @return [Client::Dispatcher]
113
- def connect_to_dispatcher( url )
114
- @dispatcher_connections ||= {}
115
- @dispatcher_connections[url] ||= Client::Dispatcher.new( url )
112
+ # @return [Client::Agent]
113
+ def connect_to_agent( url )
114
+ @agent_connections ||= {}
115
+ @agent_connections[url] ||= Client::Agent.new( url )
116
116
  end
117
117
 
118
118
  # Connects to an Instance by `url`.
@@ -14,24 +14,24 @@ class Server
14
14
  #
15
15
  # The process goes something like this:
16
16
  #
17
- # * A client issues a {#dispatch} call.
18
- # * The Dispatcher spawns and returns Instance info to the client (url, auth token, etc.).
17
+ # * A client issues a {#spawn} call.
18
+ # * The Agent spawns and returns Instance info to the client (url, auth token, etc.).
19
19
  # * The client connects to the Instance using that info.
20
20
  #
21
21
  # Once the client finishes using the RPC Instance it *must* shut it down
22
22
  # otherwise the system will be eaten away by zombie processes.
23
23
  #
24
24
  # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
25
- class Dispatcher
26
- require Options.paths.lib + 'rpc/server/dispatcher/node'
27
- require Options.paths.lib + 'rpc/server/dispatcher/service'
25
+ class Agent
26
+ require Options.paths.lib + 'rpc/server/agent/node'
27
+ require Options.paths.lib + 'rpc/server/agent/service'
28
28
 
29
29
  include Utilities
30
30
  include UI::Output
31
31
 
32
32
  SERVICE_NAMESPACE = Service
33
33
 
34
- PREFERENCE_STRATEGIES = Cuboid::OptionGroups::Dispatcher::STRATEGIES
34
+ PREFERENCE_STRATEGIES = Cuboid::OptionGroups::Agent::STRATEGIES
35
35
 
36
36
  def initialize( options = Options.instance )
37
37
  @options = options
@@ -46,20 +46,20 @@ class Dispatcher
46
46
  method.parameters.flatten.include? :block
47
47
  end
48
48
 
49
- Options.dispatcher.url = @url = @server.url
49
+ Options.agent.url = @url = @server.url
50
50
 
51
51
  prep_logging
52
52
 
53
53
  print_status 'Starting the RPC Server...'
54
54
 
55
- @server.add_handler( 'dispatcher', self )
55
+ @server.add_handler( 'agent', self )
56
56
 
57
57
  # trap interrupts and exit cleanly when required
58
58
  trap_interrupts { shutdown }
59
59
 
60
60
  @instances = []
61
61
 
62
- Cuboid::Application.application.dispatcher_services.each do |name, service|
62
+ Cuboid::Application.application.agent_services.each do |name, service|
63
63
  @server.add_handler( name.to_s, service.new( @options, self ) )
64
64
  end
65
65
 
@@ -70,7 +70,7 @@ class Dispatcher
70
70
  end
71
71
 
72
72
  def services
73
- Cuboid::Application.application.dispatcher_services.keys
73
+ Cuboid::Application.application.agent_services.keys
74
74
  end
75
75
 
76
76
  # @return [TrueClass]
@@ -80,17 +80,17 @@ class Dispatcher
80
80
  end
81
81
 
82
82
  # @param [Symbol] strategy
83
- # `:horizontal` -- Pick the Dispatcher with the least amount of workload.
84
- # `:vertical` -- Pick the Dispatcher with the most amount of workload.
83
+ # `:horizontal` -- Pick the Agent with the least amount of workload.
84
+ # `:vertical` -- Pick the Agent with the most amount of workload.
85
85
  #
86
86
  # @return [String, nil]
87
87
  # Depending on strategy and availability:
88
88
  #
89
- # * URL of the preferred Dispatcher. If not a grid member it will return
90
- # this Dispatcher's URL.
89
+ # * URL of the preferred Agent. If not a grid member it will return
90
+ # this Agent's URL.
91
91
  # * `nil` if all nodes are at max utilization or on error.
92
92
  # * `ArgumentError` -- On invalid `strategy`.
93
- def preferred( strategy = Cuboid::Options.dispatcher.strategy, &block )
93
+ def preferred( strategy = Cuboid::Options.agent.strategy, &block )
94
94
  strategy = strategy.to_sym
95
95
  if !PREFERENCE_STRATEGIES.include? strategy
96
96
  block.call :error_unknown_strategy
@@ -117,9 +117,9 @@ class Dispatcher
117
117
  end
118
118
  end
119
119
 
120
- each = proc do |neighbour, iter|
121
- connect_to_peer( neighbour ).utilization do |utilization|
122
- iter.return pick_utilization.call( neighbour, utilization )
120
+ each = proc do |peer, iter|
121
+ connect_to_peer( peer ).utilization do |utilization|
122
+ iter.return pick_utilization.call( peer, utilization )
123
123
  end
124
124
  end
125
125
 
@@ -136,25 +136,26 @@ class Dispatcher
136
136
  block.call nodes.sort_by { |_, score| adjust_score_by_strategy.call score }[0][0]
137
137
  end
138
138
 
139
- Arachni::Reactor.global.create_iterator( @node.neighbours ).map( each, after )
139
+ Arachni::Reactor.global.create_iterator( @node.peers ).map( each, after )
140
140
  end
141
141
 
142
142
  # Dispatches an {Instance}.
143
143
  #
144
- # @param [String] owner
144
+ # @param [String] options
145
+ # @option [String] strategy
146
+ # @option [String] owner
145
147
  # An owner to assign to the {Instance}.
146
- # @param [Hash] helpers
148
+ # @option [Hash] helpers
147
149
  # Hash of helper data to be added to the instance info.
148
- # @param [Boolean] load_balance
149
- # Return an {Instance} from the least burdened {Dispatcher} (when in Grid mode)
150
- # or from this one directly?
150
+ # @option [Boolean] load_balance
151
+ # Use the Grid (when available) or this one directly?
151
152
  #
152
153
  # @return [Hash, nil]
153
154
  # Depending on availability:
154
155
  #
155
156
  # * `Hash`: Connection and proc info.
156
157
  # * `nil`: Max utilization, wait for one of the instances to finish and retry.
157
- def dispatch( options = {}, &block )
158
+ def spawn( options = {}, &block )
158
159
  options = options.my_symbolize_keys
159
160
  strategy = options.delete(:strategy)
160
161
  owner = options[:owner]
@@ -173,7 +174,7 @@ class Dispatcher
173
174
  next
174
175
  end
175
176
 
176
- connect_to_peer( url ).dispatch( options.merge(
177
+ connect_to_peer( url ).spawn( options.merge(
177
178
  helpers: helpers.merge( via: @url ),
178
179
  load_balance: false
179
180
  ),
@@ -243,7 +244,7 @@ class Dispatcher
243
244
  end
244
245
 
245
246
  # @return [Float]
246
- # Workload score for this Dispatcher, calculated using {System#utilization}.
247
+ # Workload score for this Agent, calculated using {System#utilization}.
247
248
  #
248
249
  # * `0.0` => No utilization.
249
250
  # * `1.0` => Max utilization.
@@ -285,7 +286,7 @@ class Dispatcher
285
286
  end
286
287
  end
287
288
 
288
- # Starts the dispatcher's server
289
+ # Starts the agent's server
289
290
  def run
290
291
  Arachni::Reactor.global.on_error do |_, e|
291
292
  print_error "Reactor: #{e}"
@@ -314,7 +315,7 @@ class Dispatcher
314
315
  def spawn_instance( options = {}, &block )
315
316
  Processes::Instances.spawn( options.merge(
316
317
  address: @server.address,
317
- port_range: Options.dispatcher.instance_port_range,
318
+ port_range: Options.agent.instance_port_range,
318
319
  token: Utilities.generate_token,
319
320
  application: Options.paths.application
320
321
  )) do |client|
@@ -331,12 +332,12 @@ class Dispatcher
331
332
  def prep_logging
332
333
  # reroute all output to a logfile
333
334
  @logfile ||= reroute_to_file( @options.paths.logs +
334
- "/Dispatcher - #{Process.pid}-#{@options.rpc.server_port}.log" )
335
+ "/Agent - #{Process.pid}-#{@options.rpc.server_port}.log" )
335
336
  end
336
337
 
337
338
  def connect_to_peer( url )
338
339
  @rpc_clients ||= {}
339
- @rpc_clients[url] ||= Client::Dispatcher.new( url )
340
+ @rpc_clients[url] ||= Client::Agent.new( url )
340
341
  end
341
342
 
342
343
  end
@@ -111,7 +111,7 @@ class ApplicationWrapper
111
111
  busy: running?,
112
112
  application: @application.class.to_s,
113
113
  seed: Utilities.random_seed,
114
- dispatcher_url: Cuboid::Options.dispatcher.url,
114
+ agent_url: Cuboid::Options.agent.url,
115
115
  scheduler_url: Cuboid::Options.scheduler.url
116
116
  }
117
117
 
@@ -90,10 +90,10 @@ class Instance
90
90
  end
91
91
 
92
92
  # @return [String, nil]
93
- # Dispatcher URL that provided this Instance, `nil` if not provided by a
94
- # Dispatcher.
95
- def dispatcher_url
96
- @options.dispatcher.url
93
+ # Agent URL that provided this Instance, `nil` if not provided by a
94
+ # Agent.
95
+ def agent_url
96
+ @options.agent.url
97
97
  end
98
98
 
99
99
  # @param (see Cuboid::Application#restore)
@@ -6,7 +6,7 @@ require lib + 'processes/manager'
6
6
  require lib + 'processes/instances'
7
7
 
8
8
  require lib + 'rpc/client/instance'
9
- require lib + 'rpc/client/dispatcher'
9
+ require lib + 'rpc/client/agent'
10
10
 
11
11
  require lib + 'rpc/server/base'
12
12
  require lib + 'rpc/server/output'
@@ -33,9 +33,9 @@ class Server
33
33
  # * {#attach Attached} to the queue monitor and transfer the management
34
34
  # responsibility to the queue.
35
35
  #
36
- # If a {Dispatcher} has been provided, {Instance instances} will be
37
- # {Dispatcher#dispatch provided} by it.
38
- # If no {Dispatcher} has been given, {Instance instances} will be spawned on the
36
+ # If a {Agent} has been provided, {Instance instances} will be
37
+ # {Agent#spawn provided} by it.
38
+ # If no {Agent} has been given, {Instance instances} will be spawned on the
39
39
  # Scheduler machine.
40
40
  #
41
41
  # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
@@ -379,7 +379,7 @@ class Scheduler
379
379
  end
380
380
  end
381
381
 
382
- # Starts the dispatcher's server
382
+ # Starts the agent's server
383
383
  def run
384
384
  reactor.on_error do |_, e|
385
385
  print_error "Reactor: #{e}"
@@ -415,16 +415,16 @@ class Scheduler
415
415
  )
416
416
  end
417
417
 
418
- def dispatcher
419
- return if !Options.dispatcher.url
420
- @dispatcher ||= RPC::Client::Dispatcher.new( Options.dispatcher.url )
418
+ def agent
419
+ return if !Options.agent.url
420
+ @agent ||= RPC::Client::Agent.new( Options.agent.url )
421
421
  end
422
422
 
423
423
  def spawn_instance( &block )
424
- if dispatcher
424
+ if agent
425
425
  options = {
426
426
  owner: self.class.to_s,
427
- strategy: Cuboid::Options.dispatcher.strategy,
427
+ strategy: Cuboid::Options.agent.strategy,
428
428
  helpers: {
429
429
  owner: {
430
430
  url: @url
@@ -432,9 +432,9 @@ class Scheduler
432
432
  }
433
433
  }
434
434
 
435
- dispatcher.dispatch options do |info|
435
+ agent.spawn options do |info|
436
436
  if info.rpc_exception?
437
- print_error "Failed to contact Dispatcher at: #{dispatcher.url}"
437
+ print_error "Failed to contact Agent at: #{agent.url}"
438
438
  print_error "[#{info.class}] #{info.to_s}"
439
439
  block.call :error
440
440
  next
data/lib/version CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.1.0
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Cuboid::OptionGroups::Dispatcher do
3
+ describe Cuboid::OptionGroups::Agent do
4
4
  include_examples 'option_group'
5
5
  subject { described_class.new }
6
6
 
7
- %w(url instance_port_range neighbour ping_interval name).each do |method|
7
+ %w(url instance_port_range peer ping_interval name).each do |method|
8
8
  it { is_expected.to respond_to method }
9
9
  it { is_expected.to respond_to "#{method}=" }
10
10
  end