cuboid 0.0.0 → 0.0.1alpha

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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -0
  3. data/Gemfile +20 -5
  4. data/LICENSE.md +22 -0
  5. data/README.md +158 -19
  6. data/Rakefile +56 -3
  7. data/config/paths.yml +15 -0
  8. data/cuboid.gemspec +61 -23
  9. data/lib/cuboid.rb +96 -4
  10. data/lib/cuboid/application.rb +326 -0
  11. data/lib/cuboid/application/parts/data.rb +18 -0
  12. data/lib/cuboid/application/parts/report.rb +29 -0
  13. data/lib/cuboid/application/parts/state.rb +274 -0
  14. data/lib/cuboid/application/runtime.rb +25 -0
  15. data/lib/cuboid/banner.rb +13 -0
  16. data/lib/cuboid/data.rb +86 -0
  17. data/lib/cuboid/data/application.rb +52 -0
  18. data/lib/cuboid/error.rb +9 -0
  19. data/lib/cuboid/option_group.rb +129 -0
  20. data/lib/cuboid/option_groups.rb +8 -0
  21. data/lib/cuboid/option_groups/datastore.rb +23 -0
  22. data/lib/cuboid/option_groups/dispatcher.rb +38 -0
  23. data/lib/cuboid/option_groups/output.rb +14 -0
  24. data/lib/cuboid/option_groups/paths.rb +184 -0
  25. data/lib/cuboid/option_groups/report.rb +39 -0
  26. data/lib/cuboid/option_groups/rpc.rb +105 -0
  27. data/lib/cuboid/option_groups/scheduler.rb +27 -0
  28. data/lib/cuboid/option_groups/snapshot.rb +13 -0
  29. data/lib/cuboid/option_groups/system.rb +10 -0
  30. data/lib/cuboid/options.rb +254 -0
  31. data/lib/cuboid/processes.rb +13 -0
  32. data/lib/cuboid/processes/dispatchers.rb +140 -0
  33. data/lib/cuboid/processes/executables/base.rb +54 -0
  34. data/lib/cuboid/processes/executables/dispatcher.rb +5 -0
  35. data/lib/cuboid/processes/executables/instance.rb +12 -0
  36. data/lib/cuboid/processes/executables/rest_service.rb +13 -0
  37. data/lib/cuboid/processes/executables/scheduler.rb +5 -0
  38. data/lib/cuboid/processes/helpers.rb +4 -0
  39. data/lib/cuboid/processes/helpers/dispatchers.rb +23 -0
  40. data/lib/cuboid/processes/helpers/instances.rb +39 -0
  41. data/lib/cuboid/processes/helpers/processes.rb +23 -0
  42. data/lib/cuboid/processes/helpers/schedulers.rb +23 -0
  43. data/lib/cuboid/processes/instances.rb +203 -0
  44. data/lib/cuboid/processes/manager.rb +262 -0
  45. data/lib/cuboid/processes/schedulers.rb +128 -0
  46. data/lib/cuboid/report.rb +220 -0
  47. data/lib/cuboid/rest/server.rb +165 -0
  48. data/lib/cuboid/rest/server/instance_helpers.rb +99 -0
  49. data/lib/cuboid/rest/server/routes/dispatcher.rb +41 -0
  50. data/lib/cuboid/rest/server/routes/grid.rb +41 -0
  51. data/lib/cuboid/rest/server/routes/instances.rb +131 -0
  52. data/lib/cuboid/rest/server/routes/scheduler.rb +140 -0
  53. data/lib/cuboid/rpc/client.rb +3 -0
  54. data/lib/cuboid/rpc/client/base.rb +58 -0
  55. data/lib/cuboid/rpc/client/dispatcher.rb +58 -0
  56. data/lib/cuboid/rpc/client/instance.rb +100 -0
  57. data/lib/cuboid/rpc/client/instance/service.rb +37 -0
  58. data/lib/cuboid/rpc/client/scheduler.rb +46 -0
  59. data/lib/cuboid/rpc/serializer.rb +92 -0
  60. data/lib/cuboid/rpc/server/active_options.rb +38 -0
  61. data/lib/cuboid/rpc/server/application_wrapper.rb +138 -0
  62. data/lib/cuboid/rpc/server/base.rb +63 -0
  63. data/lib/cuboid/rpc/server/dispatcher.rb +317 -0
  64. data/lib/cuboid/rpc/server/dispatcher/node.rb +247 -0
  65. data/lib/cuboid/rpc/server/dispatcher/service.rb +145 -0
  66. data/lib/cuboid/rpc/server/instance.rb +338 -0
  67. data/lib/cuboid/rpc/server/output.rb +92 -0
  68. data/lib/cuboid/rpc/server/scheduler.rb +482 -0
  69. data/lib/cuboid/ruby.rb +4 -0
  70. data/lib/cuboid/ruby/array.rb +17 -0
  71. data/lib/cuboid/ruby/hash.rb +41 -0
  72. data/lib/cuboid/ruby/object.rb +32 -0
  73. data/lib/cuboid/snapshot.rb +186 -0
  74. data/lib/cuboid/state.rb +94 -0
  75. data/lib/cuboid/state/application.rb +309 -0
  76. data/lib/cuboid/state/options.rb +27 -0
  77. data/lib/cuboid/support.rb +11 -0
  78. data/lib/cuboid/support/buffer.rb +3 -0
  79. data/lib/cuboid/support/buffer/autoflush.rb +61 -0
  80. data/lib/cuboid/support/buffer/base.rb +91 -0
  81. data/lib/cuboid/support/cache.rb +7 -0
  82. data/lib/cuboid/support/cache/base.rb +226 -0
  83. data/lib/cuboid/support/cache/least_cost_replacement.rb +77 -0
  84. data/lib/cuboid/support/cache/least_recently_pushed.rb +21 -0
  85. data/lib/cuboid/support/cache/least_recently_used.rb +31 -0
  86. data/lib/cuboid/support/cache/preference.rb +31 -0
  87. data/lib/cuboid/support/cache/random_replacement.rb +20 -0
  88. data/lib/cuboid/support/crypto.rb +2 -0
  89. data/lib/cuboid/support/crypto/rsa_aes_cbc.rb +86 -0
  90. data/lib/cuboid/support/database.rb +5 -0
  91. data/lib/cuboid/support/database/base.rb +177 -0
  92. data/lib/cuboid/support/database/categorized_queue.rb +195 -0
  93. data/lib/cuboid/support/database/hash.rb +300 -0
  94. data/lib/cuboid/support/database/queue.rb +149 -0
  95. data/lib/cuboid/support/filter.rb +3 -0
  96. data/lib/cuboid/support/filter/base.rb +110 -0
  97. data/lib/cuboid/support/filter/set.rb +29 -0
  98. data/lib/cuboid/support/glob.rb +27 -0
  99. data/lib/cuboid/support/mixins.rb +8 -0
  100. data/lib/cuboid/support/mixins/observable.rb +99 -0
  101. data/lib/cuboid/support/mixins/parts.rb +20 -0
  102. data/lib/cuboid/support/mixins/profiler.rb +93 -0
  103. data/lib/cuboid/support/mixins/spec_instances.rb +65 -0
  104. data/lib/cuboid/support/mixins/terminal.rb +57 -0
  105. data/lib/cuboid/system.rb +119 -0
  106. data/lib/cuboid/system/platforms.rb +84 -0
  107. data/lib/cuboid/system/platforms/linux.rb +26 -0
  108. data/lib/cuboid/system/platforms/mixins/unix.rb +46 -0
  109. data/lib/cuboid/system/platforms/osx.rb +25 -0
  110. data/lib/cuboid/system/platforms/windows.rb +81 -0
  111. data/lib/cuboid/system/slots.rb +143 -0
  112. data/lib/cuboid/ui/output.rb +52 -0
  113. data/lib/cuboid/ui/output_interface.rb +43 -0
  114. data/lib/cuboid/ui/output_interface/abstract.rb +68 -0
  115. data/lib/cuboid/ui/output_interface/controls.rb +84 -0
  116. data/lib/cuboid/ui/output_interface/error_logging.rb +119 -0
  117. data/lib/cuboid/ui/output_interface/implemented.rb +58 -0
  118. data/lib/cuboid/ui/output_interface/personalization.rb +62 -0
  119. data/lib/cuboid/utilities.rb +155 -0
  120. data/lib/cuboid/version.rb +4 -3
  121. data/lib/version +1 -0
  122. data/logs/placeholder +0 -0
  123. data/spec/cuboid/application/parts/data_spec.rb +12 -0
  124. data/spec/cuboid/application/parts/report_spec.rb +6 -0
  125. data/spec/cuboid/application/parts/state_spec.rb +192 -0
  126. data/spec/cuboid/application/runtime_spec.rb +21 -0
  127. data/spec/cuboid/application_spec.rb +37 -0
  128. data/spec/cuboid/data/application_spec.rb +22 -0
  129. data/spec/cuboid/data_spec.rb +47 -0
  130. data/spec/cuboid/error_spec.rb +23 -0
  131. data/spec/cuboid/option_groups/datastore_spec.rb +54 -0
  132. data/spec/cuboid/option_groups/dispatcher_spec.rb +12 -0
  133. data/spec/cuboid/option_groups/output_spec.rb +11 -0
  134. data/spec/cuboid/option_groups/paths_spec.rb +184 -0
  135. data/spec/cuboid/option_groups/report_spec.rb +26 -0
  136. data/spec/cuboid/option_groups/rpc_spec.rb +53 -0
  137. data/spec/cuboid/option_groups/snapshot_spec.rb +26 -0
  138. data/spec/cuboid/option_groups/system.rb +12 -0
  139. data/spec/cuboid/options_spec.rb +218 -0
  140. data/spec/cuboid/report_spec.rb +221 -0
  141. data/spec/cuboid/rest/server_spec.rb +1205 -0
  142. data/spec/cuboid/rpc/client/base_spec.rb +151 -0
  143. data/spec/cuboid/rpc/client/dispatcher_spec.rb +13 -0
  144. data/spec/cuboid/rpc/client/instance_spec.rb +38 -0
  145. data/spec/cuboid/rpc/server/active_options_spec.rb +21 -0
  146. data/spec/cuboid/rpc/server/base_spec.rb +60 -0
  147. data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +222 -0
  148. data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +112 -0
  149. data/spec/cuboid/rpc/server/dispatcher_spec.rb +317 -0
  150. data/spec/cuboid/rpc/server/instance_spec.rb +307 -0
  151. data/spec/cuboid/rpc/server/output_spec.rb +32 -0
  152. data/spec/cuboid/rpc/server/scheduler_spec.rb +400 -0
  153. data/spec/cuboid/ruby/array_spec.rb +77 -0
  154. data/spec/cuboid/ruby/hash_spec.rb +63 -0
  155. data/spec/cuboid/ruby/object_spec.rb +22 -0
  156. data/spec/cuboid/snapshot_spec.rb +123 -0
  157. data/spec/cuboid/state/application_spec.rb +538 -0
  158. data/spec/cuboid/state/options_spec.rb +37 -0
  159. data/spec/cuboid/state_spec.rb +53 -0
  160. data/spec/cuboid/support/buffer/autoflush_spec.rb +78 -0
  161. data/spec/cuboid/support/buffer/base_spec.rb +193 -0
  162. data/spec/cuboid/support/cache/least_cost_replacement_spec.rb +61 -0
  163. data/spec/cuboid/support/cache/least_recently_pushed_spec.rb +90 -0
  164. data/spec/cuboid/support/cache/least_recently_used_spec.rb +80 -0
  165. data/spec/cuboid/support/cache/preference_spec.rb +37 -0
  166. data/spec/cuboid/support/cache/random_replacement_spec.rb +42 -0
  167. data/spec/cuboid/support/crypto/rsa_aes_cbc_spec.rb +28 -0
  168. data/spec/cuboid/support/database/categorized_queue_spec.rb +327 -0
  169. data/spec/cuboid/support/database/hash_spec.rb +204 -0
  170. data/spec/cuboid/support/database/scheduler_spec.rb +325 -0
  171. data/spec/cuboid/support/filter/set_spec.rb +19 -0
  172. data/spec/cuboid/support/glob_spec.rb +75 -0
  173. data/spec/cuboid/support/mixins/observable_spec.rb +95 -0
  174. data/spec/cuboid/system/platforms/linux_spec.rb +31 -0
  175. data/spec/cuboid/system/platforms/osx_spec.rb +32 -0
  176. data/spec/cuboid/system/platforms/windows_spec.rb +41 -0
  177. data/spec/cuboid/system/slots_spec.rb +202 -0
  178. data/spec/cuboid/system_spec.rb +105 -0
  179. data/spec/cuboid/utilities_spec.rb +131 -0
  180. data/spec/spec_helper.rb +46 -0
  181. data/spec/support/factories/placeholder +0 -0
  182. data/spec/support/factories/scan_report.rb +18 -0
  183. data/spec/support/fixtures/empty/placeholder +0 -0
  184. data/spec/support/fixtures/executables/node.rb +50 -0
  185. data/spec/support/fixtures/mock_app.rb +61 -0
  186. data/spec/support/fixtures/mock_app/test_service.rb +64 -0
  187. data/spec/support/fixtures/services/echo.rb +64 -0
  188. data/spec/support/helpers/framework.rb +3 -0
  189. data/spec/support/helpers/matchers.rb +5 -0
  190. data/spec/support/helpers/misc.rb +3 -0
  191. data/spec/support/helpers/paths.rb +15 -0
  192. data/spec/support/helpers/request_helpers.rb +38 -0
  193. data/spec/support/helpers/requires.rb +8 -0
  194. data/spec/support/helpers/resets.rb +52 -0
  195. data/spec/support/helpers/web_server.rb +15 -0
  196. data/spec/support/lib/factory.rb +107 -0
  197. data/spec/support/lib/web_server_client.rb +41 -0
  198. data/spec/support/lib/web_server_dispatcher.rb +25 -0
  199. data/spec/support/lib/web_server_manager.rb +118 -0
  200. data/spec/support/logs/placeholder +0 -0
  201. data/spec/support/pems/cacert.pem +37 -0
  202. data/spec/support/pems/client/cert.pem +37 -0
  203. data/spec/support/pems/client/foo-cert.pem +39 -0
  204. data/spec/support/pems/client/foo-key.pem +51 -0
  205. data/spec/support/pems/client/key.pem +51 -0
  206. data/spec/support/pems/server/cert.pem +37 -0
  207. data/spec/support/pems/server/key.pem +51 -0
  208. data/spec/support/reports/placeholder +0 -0
  209. data/spec/support/shared/application.rb +10 -0
  210. data/spec/support/shared/component.rb +31 -0
  211. data/spec/support/shared/component/options/base.rb +187 -0
  212. data/spec/support/shared/option_group.rb +98 -0
  213. data/spec/support/shared/support/cache.rb +419 -0
  214. data/spec/support/shared/support/filter.rb +143 -0
  215. data/spec/support/shared/system/platforms/base.rb +25 -0
  216. data/spec/support/shared/system/platforms/mixins/unix.rb +37 -0
  217. data/spec/support/snapshots/placeholder +0 -0
  218. metadata +566 -21
  219. data/.gitignore +0 -8
  220. data/bin/console +0 -15
  221. data/bin/setup +0 -8
@@ -0,0 +1,13 @@
1
+ require 'singleton'
2
+ require 'ostruct'
3
+
4
+ lib = Cuboid::Options.paths.lib
5
+ require lib + 'rpc/client/instance'
6
+ require lib + 'rpc/client/dispatcher'
7
+ require lib + 'rpc/client/scheduler'
8
+
9
+ lib = Cuboid::Options.paths.lib + 'processes/'
10
+ require lib + 'manager'
11
+ require lib + 'dispatchers'
12
+ require lib + 'instances'
13
+ require lib + 'schedulers'
@@ -0,0 +1,140 @@
1
+ module Cuboid
2
+ module Processes
3
+
4
+ #
5
+ # Helper for managing {RPC::Server::Dispatcher} processes.
6
+ #
7
+ # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
8
+ #
9
+ class Dispatchers
10
+ include Singleton
11
+ include Utilities
12
+
13
+ # @return [Array<String>] URLs of all running Dispatchers.
14
+ attr_reader :list
15
+
16
+ def initialize
17
+ @list = []
18
+ @dispatcher_connections = {}
19
+ end
20
+
21
+ # Connects to a Dispatcher by URL.
22
+ #
23
+ # @param [String] url URL of the Dispatcher.
24
+ # @param [Hash] options Options for the RPC client.
25
+ #
26
+ # @return [RPC::Client::Dispatcher]
27
+ def connect( url, options = nil )
28
+ Arachni::Reactor.global.run_in_thread if !Arachni::Reactor.global.running?
29
+
30
+ fresh = false
31
+ if options
32
+ fresh = options.delete( :fresh )
33
+ end
34
+
35
+ if fresh
36
+ @dispatcher_connections[url] = RPC::Client::Dispatcher.new( url, options )
37
+ else
38
+ @dispatcher_connections[url] ||= RPC::Client::Dispatcher.new( url, options )
39
+ end
40
+ end
41
+
42
+ # @param [Block] block Block to pass an RPC client for each Dispatcher.
43
+ def each( &block )
44
+ @list.each do |url|
45
+ block.call connect( url )
46
+ end
47
+ end
48
+
49
+ # Spawns a {RPC::Server::Dispatcher} process.
50
+ #
51
+ # @param [Hash] options
52
+ # To be passed to {Cuboid::Options#set}. Allows `address` instead of
53
+ # `rpc_server_address` and `port` instead of `rpc_port`.
54
+ #
55
+ # @return [RPC::Client::Dispatcher]
56
+ def spawn( options = {} )
57
+ fork = options.delete(:fork)
58
+
59
+ options = {
60
+ dispatcher: {
61
+ neighbour: options[:neighbour],
62
+ },
63
+ rpc: {
64
+ server_port: options[:port] || Utilities.available_port,
65
+ server_address: options[:address] || '127.0.0.1',
66
+ server_external_address: options[:external_address]
67
+ },
68
+ paths: {
69
+ application: options[:application] || Options.paths.application
70
+ }
71
+ }
72
+
73
+ if options[:rpc][:server_external_address].nil?
74
+ options[:rpc].delete :server_external_address
75
+ end
76
+
77
+ if options[:dispatcher][:neighbour].nil?
78
+ options[:dispatcher].delete :neighbour
79
+ end
80
+
81
+ pid = Manager.spawn( :dispatcher, options: options, fork: fork )
82
+
83
+ url = "#{options[:rpc][:server_address]}:#{options[:rpc][:server_port]}"
84
+ while sleep( 0.1 )
85
+ begin
86
+ connect( url, connection_pool_size: 1, max_retries: 1 ).alive?
87
+ break
88
+ rescue => e
89
+ # ap e
90
+ end
91
+ end
92
+
93
+ @list << url
94
+ connect( url, fresh: true ).tap { |c| c.pid = pid }
95
+ end
96
+
97
+ def grid_spawn( options = {} )
98
+ d = spawn( options )
99
+ spawn( options.merge neighbour: d.url )
100
+ end
101
+
102
+ # @note Will also kill all Instances started by the Dispatcher.
103
+ #
104
+ # @param [String] url URL of the Dispatcher to kill.
105
+ def kill( url )
106
+ dispatcher = connect( url )
107
+ Manager.kill_many dispatcher.statistics['consumed_pids']
108
+ Manager.kill dispatcher.pid
109
+ rescue => e
110
+ #ap e
111
+ #ap e.backtrace
112
+ nil
113
+ ensure
114
+ @list.delete( url )
115
+ @dispatcher_connections.delete( url )
116
+ end
117
+
118
+ # Kills all {Dispatchers #list}.
119
+ def killall
120
+ @list.dup.each do |url|
121
+ kill url
122
+ end
123
+ end
124
+
125
+ def self.method_missing( sym, *args, &block )
126
+ if instance.respond_to?( sym )
127
+ instance.send( sym, *args, &block )
128
+ else
129
+ super( sym, *args, &block )
130
+ end
131
+ end
132
+
133
+ def self.respond_to?( m )
134
+ super( m ) || instance.respond_to?( m )
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,54 @@
1
+ require 'base64'
2
+
3
+ $options = Marshal.load( Base64.strict_decode64( ARGV.pop ) )
4
+
5
+ if !$options[:without_cuboid]
6
+ require 'cuboid'
7
+
8
+ include Cuboid
9
+
10
+ cuboid_options = Marshal.load( Base64.strict_decode64( ENV['CUBOID_SPAWN_OPTIONS'] ) )
11
+ Options.update cuboid_options
12
+
13
+ require( Options.paths.application ) if Options.paths.application
14
+ else
15
+ if Gem.win_platform?
16
+ require 'Win32API'
17
+ require 'win32ole'
18
+ end
19
+ end
20
+
21
+ def ppid
22
+ $options[:ppid]
23
+ end
24
+
25
+ def parent_alive?
26
+ # Windows is not big on POSIX so try it its own way if possible.
27
+ if Gem.win_platform?
28
+ begin
29
+ alive = false
30
+ wmi = WIN32OLE.connect( 'winmgmts://' )
31
+ processes = wmi.ExecQuery( "select ProcessId from win32_process where ProcessID='#{ppid}'")
32
+ processes.each do |proc|
33
+ proc.ole_free
34
+ alive = true
35
+ end
36
+ processes.ole_free
37
+ wmi.ole_free
38
+
39
+ return alive
40
+ rescue WIN32OLERuntimeError
41
+ end
42
+ end
43
+
44
+ !!(Process.kill( 0, ppid ) rescue false)
45
+ end
46
+
47
+ def puts_stderr( str )
48
+ return if $stderr.closed?
49
+
50
+ $stderr.puts str
51
+ rescue
52
+ end
53
+
54
+ load ARGV.pop
@@ -0,0 +1,5 @@
1
+ require Options.paths.lib + 'rpc/server/dispatcher'
2
+
3
+ Arachni::Reactor.global.run do
4
+ RPC::Server::Dispatcher.new
5
+ end
@@ -0,0 +1,12 @@
1
+ require Options.paths.lib + 'rpc/server/instance'
2
+
3
+ if (socket = $options[:socket])
4
+ Options.rpc.server_address = nil
5
+ Options.rpc.server_external_address = nil
6
+ Options.rpc.server_port = nil
7
+ Options.rpc.server_socket = socket
8
+ elsif (port = $options[:port])
9
+ Options.rpc.server_port = port
10
+ end
11
+
12
+ RPC::Server::Instance.new( Options, $options[:token] )
@@ -0,0 +1,13 @@
1
+ require Options.paths.lib + 'rest/server'
2
+
3
+ Rest::Server.run!(
4
+ port: Options.rpc.server_port,
5
+ bind: Options.rpc.server_address,
6
+
7
+ username: Options.datastore['username'],
8
+ password: Options.datastore['password'],
9
+
10
+ ssl_ca: Options.rpc.ssl_ca,
11
+ ssl_key: Options.rpc.server_ssl_private_key,
12
+ ssl_certificate: Options.rpc.server_ssl_certificate
13
+ )
@@ -0,0 +1,5 @@
1
+ require Options.paths.lib + 'rpc/server/scheduler'
2
+
3
+ Arachni::Reactor.global.run do
4
+ RPC::Server::Scheduler.new
5
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'helpers/processes'
2
+ require_relative 'helpers/dispatchers'
3
+ require_relative 'helpers/instances'
4
+ require_relative 'helpers/schedulers'
@@ -0,0 +1,23 @@
1
+ # @param (see Cuboid::Processes::Dispatchers#spawn)
2
+ # @return (see Cuboid::Processes::Dispatchers#spawn)
3
+ def dispatcher_spawn( *args )
4
+ Cuboid::Processes::Dispatchers.spawn( *args )
5
+ end
6
+
7
+ # @param (see Cuboid::Processes::Dispatchers#kill)
8
+ # @return (see Cuboid::Processes::Dispatchers#kill)
9
+ def dispatcher_kill( *args )
10
+ Cuboid::Processes::Dispatchers.kill( *args )
11
+ end
12
+
13
+ # @param (see Cuboid::Processes::Dispatchers#killall)
14
+ # @return (see Cuboid::Processes::Dispatchers#killall)
15
+ def dispatcher_killall
16
+ Cuboid::Processes::Dispatchers.killall
17
+ end
18
+
19
+ # @param (see Cuboid::Processes::Dispatchers#connect)
20
+ # @return (see Cuboid::Processes::Dispatchers#connect)
21
+ def dispatcher_connect( *args )
22
+ Cuboid::Processes::Dispatchers.connect( *args )
23
+ end
@@ -0,0 +1,39 @@
1
+ # @param (see Cuboid::Processes::Instances#spawn)
2
+ # @return (see Cuboid::Processes::Instances#spawn)
3
+ def instance_spawn( *args )
4
+ Cuboid::Processes::Instances.spawn( *args )
5
+ end
6
+
7
+ # @param (see Cuboid::Processes::Instances#grid_spawn)
8
+ # @return (see Cuboid::Processes::Instances#grid_spawn)
9
+ def instance_grid_spawn( *args )
10
+ Cuboid::Processes::Instances.grid_spawn( *args )
11
+ end
12
+
13
+ # @param (see Cuboid::Processes::Instances#dispatcher_spawn)
14
+ # @return (see Cuboid::Processes::Instances#dispatcher_spawn)
15
+ def instance_dispatcher_spawn( *args )
16
+ Cuboid::Processes::Instances.dispatcher.spawn( *args )
17
+ end
18
+
19
+ def instance_kill( url )
20
+ Cuboid::Processes::Instances.kill url
21
+ end
22
+
23
+ # @param (see Cuboid::Processes::Instances#killall)
24
+ # @return (see Cuboid::Processes::Instances#killall)
25
+ def instance_killall
26
+ Cuboid::Processes::Instances.killall
27
+ end
28
+
29
+ # @param (see Cuboid::Processes::Instances#connect)
30
+ # @return (see Cuboid::Processes::Instances#connect)
31
+ def instance_connect( *args )
32
+ Cuboid::Processes::Instances.connect( *args )
33
+ end
34
+
35
+ # @param (see Cuboid::Processes::Instances#token_for)
36
+ # @return (see Cuboid::Processes::Instances#token_for)
37
+ def instance_token_for( *args )
38
+ Cuboid::Processes::Instances.token_for( *args )
39
+ end
@@ -0,0 +1,23 @@
1
+ # @param (see Cuboid::Processes::Manager#kill_reactor)
2
+ # @return (see Cuboid::Processes::Manager#kill_reactor)
3
+ def process_kill_reactor( *args )
4
+ Cuboid::Processes::Manager.kill_reactor( *args )
5
+ end
6
+
7
+ # @param (see Cuboid::Processes::Manager#kill)
8
+ # @return (see Cuboid::Processes::Manager#kill)
9
+ def process_kill( *args )
10
+ Cuboid::Processes::Manager.kill( *args )
11
+ end
12
+
13
+ # @param (see Cuboid::Processes::Manager#killall)
14
+ # @return (see Cuboid::Processes::Manager#killall)
15
+ def process_killall( *args )
16
+ Cuboid::Processes::Manager.killall( *args )
17
+ end
18
+
19
+ # @param (see Cuboid::Processes::Manager#kill_many)
20
+ # @return (see Cuboid::Processes::Manager#kill_many)
21
+ def process_kill_many( *args )
22
+ Cuboid::Processes::Manager.kill_many( *args )
23
+ end
@@ -0,0 +1,23 @@
1
+ # @param (see Cuboid::Processes::Schedulers#spawn)
2
+ # @return (see Cuboid::Processes::Schedulers#spawn)
3
+ def scheduler_spawn( *args )
4
+ Cuboid::Processes::Schedulers.spawn( *args )
5
+ end
6
+
7
+ # @param (see Cuboid::Processes::Schedulers#kill)
8
+ # @return (see Cuboid::Processes::Schedulers#kill)
9
+ def scheduler_kill( *args )
10
+ Cuboid::Processes::Schedulers.kill( *args )
11
+ end
12
+
13
+ # @param (see Cuboid::Processes::Schedulers#killall)
14
+ # @return (see Cuboid::Processes::Schedulers#killall)
15
+ def scheduler_killall
16
+ Cuboid::Processes::Schedulers.killall
17
+ end
18
+
19
+ # @param (see Cuboid::Processes::Schedulers#connect)
20
+ # @return (see Cuboid::Processes::Schedulers#connect)
21
+ def scheduler_connect( *args )
22
+ Cuboid::Processes::Schedulers.connect( *args )
23
+ end
@@ -0,0 +1,203 @@
1
+ module Cuboid
2
+ module Processes
3
+
4
+ #
5
+ # Helper for managing {RPC::Server::Instance} processes.
6
+ #
7
+ # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
8
+ #
9
+ class Instances
10
+ include Singleton
11
+ include Utilities
12
+
13
+ # @return [Array<String>] URLs and tokens of all running Instances.
14
+ attr_reader :list
15
+
16
+ def initialize
17
+ @list = {}
18
+ @instance_connections = {}
19
+ end
20
+
21
+ #
22
+ # Connects to a Instance by URL.
23
+ #
24
+ # @param [String] url URL of the Dispatcher.
25
+ # @param [String] token
26
+ # Authentication token -- only need be provided once.
27
+ #
28
+ # @return [RPC::Client::Instance]
29
+ #
30
+ def connect( url, token = nil )
31
+ Arachni::Reactor.global.run_in_thread if !Arachni::Reactor.global.running?
32
+
33
+ token ||= @list[url]
34
+ @list[url] ||= token
35
+
36
+ @instance_connections[url] ||= RPC::Client::Instance.new( url, token )
37
+ end
38
+
39
+ # @param [Block] block Block to pass an RPC client for each Instance.
40
+ def each( &block )
41
+ @list.keys.each do |url|
42
+ block.call connect( url )
43
+ end
44
+ end
45
+
46
+ #
47
+ # @param [String, RPC::Client::Instance] client_or_url
48
+ #
49
+ # @return [String] Cached authentication token for the given Instance.
50
+ #
51
+ def token_for( client_or_url )
52
+ @list[client_or_url.is_a?( String ) ? client_or_url : client_or_url.url ]
53
+ end
54
+
55
+ # Spawns an {RPC::Server::Instance} process.
56
+ #
57
+ # @param [Hash] options
58
+ # To be passed to {Cuboid::Options#set}. Allows `address` instead of
59
+ # `rpc_server_address` and `port` instead of `rpc_port`.
60
+ #
61
+ # @return [RPC::Client::Instance, Integer]
62
+ # RPC client and PID.
63
+ def spawn( options = {}, &block )
64
+ token = options.delete(:token) || Utilities.generate_token
65
+ fork = options.delete(:fork)
66
+
67
+ port_range = options.delete( :port_range )
68
+
69
+ options = {
70
+ rpc: {
71
+ server_socket: options[:socket],
72
+ server_port: options[:port] || Utilities.available_port( port_range ),
73
+ server_address: options[:address] || '127.0.0.1'
74
+ },
75
+ paths: {
76
+ application: options[:application] || Options.paths.application
77
+ }
78
+ }
79
+
80
+ url = nil
81
+ if options[:rpc][:server_socket]
82
+ url = options[:rpc][:server_socket]
83
+
84
+ options[:rpc].delete :server_address
85
+ options[:rpc].delete :server_port
86
+ else
87
+ url = "#{options[:rpc][:server_address]}:#{options[:rpc][:server_port]}"
88
+ end
89
+
90
+ pid = Manager.spawn( :instance, options: options, token: token, fork: fork )
91
+
92
+ System.slots.use pid
93
+
94
+ client = connect( url, token )
95
+ client.pid = pid
96
+
97
+ if block_given?
98
+ client.when_ready do
99
+ block.call client
100
+ end
101
+ else
102
+ while sleep( 0.1 )
103
+ begin
104
+ client.alive?
105
+ break
106
+ rescue => e
107
+ # ap "#{e.class}: #{e}"
108
+ # ap e.backtrace
109
+ end
110
+ end
111
+
112
+ client
113
+ end
114
+ end
115
+
116
+ # Starts {RPC::Server::Dispatcher} grid and returns a high-performance Instance.
117
+ #
118
+ # @param [Hash] options
119
+ # @option options [Integer] :grid_size (3) Amount of Dispatchers to spawn.
120
+ #
121
+ # @return [RPC::Client::Instance]
122
+ def grid_spawn(options = {} )
123
+ options[:grid_size] ||= 3
124
+
125
+ last_member = nil
126
+ options[:grid_size].times do |i|
127
+ last_member = Dispatchers.spawn(
128
+ neighbour: last_member ? last_member.url : last_member,
129
+ pipe_id: Utilities.available_port.to_s + Utilities.available_port.to_s
130
+ )
131
+ end
132
+
133
+ info = nil
134
+ info = last_member.dispatch while !info && sleep( 0.1 )
135
+
136
+ connect( info['url'], info['token'] )
137
+ end
138
+
139
+ # Starts {RPC::Server::Dispatcher} and returns an Instance.
140
+ #
141
+ # @return [RPC::Client::Instance]
142
+ def dispatcher_spawn
143
+ info = Dispatchers.spawn.dispatch
144
+ connect( info['url'], info['token'] )
145
+ end
146
+
147
+ def kill( url )
148
+ service = connect( url )
149
+ service.consumed_pids do |pids|
150
+ service.shutdown do
151
+ # Make sure....
152
+ Manager.kill_many pids
153
+ end
154
+ end
155
+
156
+ @list.delete url
157
+ end
158
+
159
+ # Kills all {Instances #list}.
160
+ def killall
161
+ pids = []
162
+ each do |instance|
163
+ begin
164
+ Timeout.timeout 5 do
165
+ pids |= instance.consumed_pids
166
+ end
167
+ rescue => e
168
+ #ap e
169
+ #ap e.backtrace
170
+ end
171
+ end
172
+
173
+ each do |instance|
174
+ begin
175
+ Timeout.timeout 5 do
176
+ instance.shutdown
177
+ end
178
+ rescue => e
179
+ #ap e
180
+ #ap e.backtrace
181
+ end
182
+ end
183
+
184
+ @list.clear
185
+ @instance_connections.clear
186
+ Manager.kill_many pids
187
+ end
188
+
189
+ def self.method_missing( sym, *args, &block )
190
+ if instance.respond_to?( sym )
191
+ instance.send( sym, *args, &block )
192
+ else
193
+ super( sym, *args, &block )
194
+ end
195
+ end
196
+
197
+ def self.respond_to?( m )
198
+ super( m ) || instance.respond_to?( m )
199
+ end
200
+ end
201
+
202
+ end
203
+ end