spider-gazelle 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d98f7022babe544f38425eacb223337cef347ade
4
- data.tar.gz: d214d5a1192828a1d272f7955817f64f9829c7b9
3
+ metadata.gz: 49d9e0d9dee57cc23287f2155e6ebe81137e3f15
4
+ data.tar.gz: 385f9ee18cdc18dab2b1de1f34b689968c617e8a
5
5
  SHA512:
6
- metadata.gz: 659f91228f5efc1879874407ae54ea20c15df0b9129eb30f8d96b59b57c4979e2da5a4ff0b6686ecd701c4976b36903571156401c93b0c0384b218b08b249d5d
7
- data.tar.gz: b4264bc65bad3ec4736f25d38b63e0e0ec3e37617b12f794936a9ed66f0081ef114d206856635e6778d991900c7edf9b6ae9d919baef132ff9407510a2ff28cb
6
+ metadata.gz: 932d6770571115d8e01d8e039725222929e7da5800be5d3ec9730505e97e1f8d153a76dfab4bbfb8ce8deea47993deb7d5a1797fabb7d869e5349c512108b6f7
7
+ data.tar.gz: 3b33aa02ef5fad6b922ef577e22c3b209cd6f2db336f85d74c666f75cc38574dec6db3ae7b76ce2ab1bd50b7af33fdbdc8d26893943f0e1982e3bb3303fff102
@@ -73,25 +73,21 @@ module SpiderGazelle
73
73
  # ---------------------------------------
74
74
  def launch_spider(args)
75
75
  require 'securerandom'
76
- require 'thread'
77
76
 
78
77
  @password ||= SecureRandom.hex
79
- #cmd = "#{EXEC_NAME} -s #{@password} #{Shellwords.join(args)}"
80
- cmd = [EXEC_NAME, '-s', @password] + args
81
78
 
82
- Thread.new do
83
- result = system(*cmd)
79
+ #cmd = "#{EXEC_NAME} -s #{@password} #{Shellwords.join(args)}"
84
80
 
85
- # TODO:: We need to detect a failed load
86
- # This is a little more tricky as spiders
87
- # may come and go without this process exiting
81
+ thread = Reactor.instance.thread
82
+ spider = thread.spawn(EXEC_NAME, args: (['-s', @password] + args), mode: :inherit)
83
+ spider.finally do
84
+ signaller = ::SpiderGazelle::Signaller.instance
85
+ signaller.panic!('Unexpected spider exit') unless signaller.shutting_down
88
86
  end
89
87
  end
90
88
 
91
89
  # This is called when a spider process starts
92
90
  def start_spider(signaller, logger, options)
93
- logger.set_client signaller.pipe unless options[0][:isolate]
94
-
95
91
  require 'spider-gazelle/spider'
96
92
  Spider.instance.run!(options)
97
93
  end
@@ -5,7 +5,7 @@ require 'libuv'
5
5
  module SpiderGazelle
6
6
  class Logger
7
7
  include Singleton
8
- attr_reader :level, :thread, :pipe
8
+ attr_reader :level, :thread, :stdout
9
9
  attr_accessor :formatter
10
10
 
11
11
 
@@ -22,19 +22,14 @@ module SpiderGazelle
22
22
 
23
23
  def initialize
24
24
  @thread = ::Libuv::Reactor.default
25
+ @stdout = @thread.pipe
26
+ @stdout.open(1)
25
27
  @level = DEFAULT_LEVEL
26
- @write = method(:server_write)
27
28
  end
28
29
 
29
30
 
30
31
  def self.log(data)
31
- Logger.instance.server_write(data)
32
- end
33
-
34
-
35
- def set_client(uv_io)
36
- @pipe = uv_io
37
- @write = method(:client_write)
32
+ Logger.instance.stdout.write(data)
38
33
  end
39
34
 
40
35
  def level=(level)
@@ -83,7 +78,7 @@ module SpiderGazelle
83
78
  def verbose(msg = nil)
84
79
  if @verbose
85
80
  msg = yield if block_given?
86
- @write.call ">> #{msg}\n"
81
+ @stdout.write ">> #{msg}\n"
87
82
  end
88
83
  end
89
84
 
@@ -95,11 +90,6 @@ module SpiderGazelle
95
90
  error(message)
96
91
  end
97
92
 
98
- # NOTE:: should only be called on reactor thread
99
- def server_write(msg)
100
- STDOUT.write msg
101
- end
102
-
103
93
 
104
94
  protected
105
95
 
@@ -107,13 +97,8 @@ module SpiderGazelle
107
97
  def log(level, msg)
108
98
  output = "[#{level}] #{msg}\n"
109
99
  @thread.schedule do
110
- @write.call output
100
+ @stdout.write output
111
101
  end
112
102
  end
113
-
114
- # NOTE:: should only be called on reactor thread
115
- def client_write(msg)
116
- @pipe.write "\x02Logger log #{msg}\x03"
117
- end
118
103
  end
119
104
  end
@@ -38,16 +38,17 @@ module SpiderGazelle
38
38
  end
39
39
 
40
40
  @thread.schedule do
41
- return if @shutdown_called
42
- @shutdown_called = true
41
+ if not @shutdown_called
42
+ @shutdown_called = true
43
43
 
44
- # Signaller will manage the shutdown of the gazelles
45
- signaller = Signaller.instance.shutdown
46
- signaller.finally do
47
- @thread.stop
48
- # New line on exit to avoid any ctrl-c characters
49
- # We check for pipe as we only want the master process to print this
50
- puts "\nSpider-Gazelle leaps through the veldt\n" unless @logger.pipe
44
+ # Signaller will manage the shutdown of the gazelles
45
+ signaller = Signaller.instance.shutdown
46
+ signaller.finally do
47
+ @thread.stop
48
+ # New line on exit to avoid any ctrl-c characters
49
+ # We check for pipe as we only want the master process to print this
50
+ puts "\nSpider-Gazelle leaps through the veldt\n"
51
+ end
51
52
  end
52
53
  end
53
54
  end
@@ -8,7 +8,7 @@ module SpiderGazelle
8
8
  include Singleton
9
9
 
10
10
 
11
- attr_reader :thread, :pipe
11
+ attr_reader :thread, :pipe, :is_connected, :shutting_down
12
12
  attr_accessor :gazelle
13
13
 
14
14
 
@@ -19,7 +19,8 @@ module SpiderGazelle
19
19
  # This is used to check if an instance of spider-gazelle is already running
20
20
  @is_master = false
21
21
  @is_client = false
22
- @is_connected = false
22
+ @is_connected = false
23
+ @shutting_down = false
23
24
  @client_check = @thread.defer
24
25
  @validated = [] # Set requires more processing
25
26
  @validating = {}
@@ -42,6 +43,7 @@ module SpiderGazelle
42
43
 
43
44
  def shutdown
44
45
  defer = @thread.defer
46
+ @shutting_down = true
45
47
 
46
48
  # Close the SIGNAL_SERVER pipe
47
49
  @pipe.close if @is_connected
@@ -115,7 +117,6 @@ module SpiderGazelle
115
117
  @pipe.finally do
116
118
  if @is_client
117
119
  @is_connected = false
118
- panic!(nil)
119
120
  else
120
121
  # Assume the role of master
121
122
  become_sg_master
@@ -154,7 +155,7 @@ module SpiderGazelle
154
155
  # If all the process connections are gone then we want to shutdown
155
156
  # This should never happen under normal conditions
156
157
  if @validated.length == 0
157
- Reactor.instance.shutdown
158
+ Reactor.instance.shutdown unless @shutting_down
158
159
  end
159
160
  end
160
161
 
@@ -174,7 +175,7 @@ module SpiderGazelle
174
175
  #@logger.error "Master pipe went missing: #{reason}"
175
176
  # Server most likely exited
176
177
  # We'll shutdown here
177
- STDERR.puts "\n\npanic! #{reason.inspect}\n\n\n"
178
+ STDERR.puts "\n\npanic! #{reason.inspect}\n#{caller.join("\n")}\n\n\n"
178
179
  STDERR.flush
179
180
  Reactor.instance.shutdown
180
181
  end
@@ -101,7 +101,7 @@ module SpiderGazelle
101
101
  def shutdown(finished)
102
102
  @shutdown_defer = finished
103
103
 
104
- @logger.verbose { "Spider Pid: #{Process.pid} shutting down" }
104
+ @logger.verbose { "Spider Pid: #{Process.pid} shutting down (loaded #{@loaded})" }
105
105
 
106
106
  if @loaded
107
107
  perform_shutdown
@@ -3,104 +3,95 @@
3
3
  require 'websocket/driver'
4
4
  require 'forwardable'
5
5
 
6
- module SpiderGazelle
7
- class Websocket < ::Libuv::Q::DeferredPromise
8
- attr_reader :env, :url, :reactor, :socket
6
+ class SpiderGazelle::Websocket < ::Libuv::Q::DeferredPromise
7
+ attr_reader :env, :url, :reactor, :socket
9
8
 
9
+ extend ::Forwardable
10
+ def_delegators :@driver, :start, :ping, :protocol, :ready_state, :set_header, :state, :close
11
+ def_delegators :@socket, :write, :peername
10
12
 
11
- RACK_URL_SCHEME = 'rack.url_scheme'
12
- HTTP_HOST = 'HTTP_HOST'
13
- REQUEST_URI= 'REQUEST_URI'
14
- HTTPS = 'https'
13
+ def initialize(tcp, env)
14
+ @socket, @env = tcp, env
15
15
 
16
+ # Initialise the promise
17
+ super tcp.reactor, tcp.reactor.defer
16
18
 
17
- extend Forwardable
18
- def_delegators :@driver, :start, :ping, :protocol, :ready_state, :set_header, :state, :close
19
- def_delegators :@socket, :write, :peername
19
+ scheme = env['rack.url_scheme'] == 'https' ? 'wss://' : 'ws://'
20
+ @url = scheme + env['HTTP_HOST'] + env['REQUEST_URI']
21
+ @driver = ::WebSocket::Driver.rack self
20
22
 
21
- def initialize(tcp, env)
22
- @socket, @env = tcp, env
23
+ # Pass data from the socket to the driver
24
+ @socket.progress &method(:socket_read)
25
+ @socket.finally &method(:socket_close)
23
26
 
24
- # Initialise the promise
25
- super tcp.reactor, tcp.reactor.defer
26
27
 
27
- scheme = env[RACK_URL_SCHEME] == HTTPS ? 'wss://' : 'ws://'
28
- @url = scheme + env[HTTP_HOST] + env[REQUEST_URI]
29
- @driver = ::WebSocket::Driver.rack self
30
-
31
- # Pass data from the socket to the driver
32
- @socket.progress &method(:socket_read)
33
- @socket.finally &method(:socket_close)
34
-
35
-
36
- # Driver has indicated that it is closing
37
- # We'll close the socket after writing any remaining data
38
- @driver.on :close, &method(:on_close)
39
- @driver.on :message, &method(:on_message)
40
- @driver.on :error, &method(:on_error)
41
- end
28
+ # Driver has indicated that it is closing
29
+ # We'll close the socket after writing any remaining data
30
+ @driver.on :close, &method(:on_close)
31
+ @driver.on :message, &method(:on_message)
32
+ @driver.on :error, &method(:on_error)
33
+ end
42
34
 
43
- # Write some text to the websocket connection
44
- #
45
- # @param string [String] a string of data to be sent to the far end
46
- def text(string)
47
- @reactor.schedule { @driver.text(string.to_s) }
48
- end
35
+ # Write some text to the websocket connection
36
+ #
37
+ # @param string [String] a string of data to be sent to the far end
38
+ def text(string)
39
+ @reactor.schedule { @driver.text(string.to_s) }
40
+ end
49
41
 
50
- # Write some binary data to the websocket connection
51
- #
52
- # @param array [Array] an array of bytes to be sent to the far end
53
- def binary(array)
54
- @reactor.schedule { @driver.binary(array.to_a) }
55
- end
42
+ # Write some binary data to the websocket connection
43
+ #
44
+ # @param array [Array] an array of bytes to be sent to the far end
45
+ def binary(array)
46
+ @reactor.schedule { @driver.binary(array.to_a) }
47
+ end
56
48
 
57
- # Used to define a callback when data is received from the client
58
- #
59
- # @param callback [Proc] the callback to be called when data is received
60
- def progress(callback = nil, &blk)
61
- @progress = callback || blk
62
- end
49
+ # Used to define a callback when data is received from the client
50
+ #
51
+ # @param callback [Proc] the callback to be called when data is received
52
+ def progress(callback = nil, &blk)
53
+ @progress = callback || blk
54
+ end
63
55
 
64
- # Used to define a callback when the websocket connection is established
65
- # Data sent before this callback is buffered.
66
- #
67
- # @param callback [Proc] the callback to be triggered on establishment
68
- def on_open(callback = nil, &blk)
69
- callback ||= blk
70
- @driver.on :open, &callback
71
- end
56
+ # Used to define a callback when the websocket connection is established
57
+ # Data sent before this callback is buffered.
58
+ #
59
+ # @param callback [Proc] the callback to be triggered on establishment
60
+ def on_open(callback = nil, &blk)
61
+ callback ||= blk
62
+ @driver.on :open, &callback
63
+ end
72
64
 
73
- protected
65
+ protected
74
66
 
75
- def socket_read(data, tcp)
76
- begin
77
- @driver.parse data
78
- rescue => e
79
- # Prevent hanging sockets
80
- @socket.close
81
- raise e
82
- end
67
+ def socket_read(data, tcp)
68
+ begin
69
+ @driver.parse data
70
+ rescue => e
71
+ # Prevent hanging sockets
72
+ @socket.close
73
+ raise e
83
74
  end
75
+ end
84
76
 
85
- def socket_close
86
- if @shutdown_called.nil?
87
- @defer.reject WebSocket::Driver::CloseEvent.new(1006, 'connection was closed unexpectedly')
88
- end
77
+ def socket_close
78
+ if @shutdown_called.nil?
79
+ @defer.reject WebSocket::Driver::CloseEvent.new(1006, 'connection was closed unexpectedly')
89
80
  end
81
+ end
90
82
 
91
83
 
92
- def on_message(event)
93
- @progress.call(event.data, self) unless @progress.nil?
94
- end
84
+ def on_message(event)
85
+ @progress.call(event.data, self) unless @progress.nil?
86
+ end
95
87
 
96
- def on_error(event)
97
- @defer.reject event
98
- end
88
+ def on_error(event)
89
+ @defer.reject event
90
+ end
99
91
 
100
- def on_close(event)
101
- @shutdown_called = true
102
- @socket.shutdown
103
- @defer.resolve event
104
- end
92
+ def on_close(event)
93
+ @shutdown_called = true
94
+ @socket.shutdown
95
+ @defer.resolve event
105
96
  end
106
97
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SpiderGazelle
4
- VERSION = '3.0.5'
4
+ VERSION = '3.0.6'
5
5
  EXEC_NAME = 'sg'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spider-gazelle
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.5
4
+ version: 3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen von Takach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-27 00:00:00.000000000 Z
11
+ date: 2017-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-parser
@@ -189,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  version: '0'
190
190
  requirements: []
191
191
  rubyforge_project:
192
- rubygems_version: 2.6.10
192
+ rubygems_version: 2.6.12
193
193
  signing_key:
194
194
  specification_version: 4
195
195
  summary: A fast, parallel and concurrent web server for ruby