spider-gazelle 0.1.2 → 0.1.3

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: 389b76b304d2c434532df00b18f0e772b7bca616
4
- data.tar.gz: de17af1941a3ce3cf24a65ec069a1e33bf5490f6
3
+ metadata.gz: ddf67f2f83bb093e412603cfaccbdff9465fd492
4
+ data.tar.gz: 418b883c22f28aec01358f7e1583b5102eed3452
5
5
  SHA512:
6
- metadata.gz: d3751fe5f50137772b2b434cf8ab2bbbeb8c597e343977ca99fd43de1cc5592f7897d756ae04e1ba4d81adbe60de712ab6f8169a42eb3a62bc9b91b6ccd60d90
7
- data.tar.gz: 1bd6d81f822682a1c52b0c1f843e0f3323f69cc80e7effd755c092874fd6019692f8a705d92d87509393654034ac3a0d885b4c43ad88660f2247fc6834df5734
6
+ metadata.gz: 8e6bf5475f273760fb5bcbcd0e73988a292d3f473d95e96a6b043168b303b46403fac5e4c2b1201693ef2b51cdd3b250b1ef593c43ba2407e2e006443101556c
7
+ data.tar.gz: 5c62a4b4dd5a142b2a0f8090cac2ff67a2004305bf9c0ca78d2c4c8cb4e7043115d8b9b338180d76ab249af439838fce58ea093bac83dbc26d3936fec5c77659
data/bin/sg CHANGED
@@ -64,29 +64,6 @@ ENV['RACK_ENV'] = options[:environment].to_s
64
64
  # Force process mode on Windows (pipes + sockets not working at the moment)
65
65
  ENV['SG_MODE'] = 'no_ipc' if ::FFI::Platform.windows?
66
66
 
67
- ::Libuv::Loop.default.run do |logger|
68
- logger.progress do |level, errorid, error|
69
- begin
70
- puts "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
71
- rescue Exception
72
- p 'error in gazelle logger'
73
- end
74
- end
75
-
76
- puts "Look out! Here comes Spider-Gazelle #{::SpiderGazelle::VERSION}!"
77
- puts "* Environment: #{ENV['RACK_ENV']} on #{RUBY_ENGINE || 'ruby'} #{RUBY_VERSION}"
78
- server = ::SpiderGazelle::Spider.instance
79
- server.loaded.then do
80
- puts "* Loading: #{options[:rackup]}"
81
- server.load(options[:rackup], options).catch(proc {|e|
82
- puts "#{e.message}\n#{e.backtrace.join("\n") unless e.backtrace.nil?}\n"
83
- }).finally do
84
- # This will execute if the TCP binding is lost
85
- server.shutdown
86
- end
87
-
88
- puts "* Listening on tcp://#{options[:host]}:#{options[:port]}"
89
- end
90
- end
67
+ ::SpiderGazelle::Spider.run options[:rackup], options
91
68
 
92
69
  puts "\nSpider-Gazelle leaps through the veldt"
@@ -3,45 +3,37 @@ require 'spider-gazelle'
3
3
 
4
4
 
5
5
  module Rack
6
- module Handler
7
- module SpiderGazelle
8
- DEFAULT_OPTIONS = {
9
- :Host => '0.0.0.0',
10
- :Port => 8080,
11
- :Verbose => false
12
- }
13
-
14
- def self.run(app, options = {})
15
- options = DEFAULT_OPTIONS.merge(options)
16
-
17
- if options[:Verbose]
18
- app = Rack::CommonLogger.new(app, STDOUT)
19
- end
20
-
21
- if options[:environment]
22
- ENV['RACK_ENV'] = options[:environment].to_s
23
- end
24
-
25
- server = ::SpiderGazelle::Spider.new(app, options)
26
-
27
- puts "Spider-Gazelle #{::SpiderGazelle::VERSION} starting..."
28
- puts "* Environment: #{ENV['RACK_ENV']}"
29
- puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
30
-
31
- yield server if block_given?
32
-
33
- server.run
34
- end
35
-
36
- def self.valid_options
37
- {
38
- "Host=HOST" => "Hostname to listen on (default: 0.0.0.0)",
39
- "Port=PORT" => "Port to listen on (default: 8080)",
40
- "Quiet" => "Don't report each request"
41
- }
42
- end
43
- end
44
-
45
- register :sg, SpiderGazelle
46
- end
6
+ module Handler
7
+ module SpiderGazelle
8
+ DEFAULT_OPTIONS = {
9
+ :Host => '0.0.0.0',
10
+ :Port => 8080,
11
+ :Verbose => false
12
+ }
13
+
14
+ def self.run(app, options = {})
15
+ options = DEFAULT_OPTIONS.merge(options)
16
+
17
+ if options[:Verbose]
18
+ app = Rack::CommonLogger.new(app, STDOUT)
19
+ end
20
+
21
+ if options[:environment]
22
+ ENV['RACK_ENV'] = options[:environment].to_s
23
+ end
24
+
25
+ ::SpiderGazelle::Spider.run app, options
26
+ end
27
+
28
+ def self.valid_options
29
+ {
30
+ "Host=HOST" => "Hostname to listen on (default: 0.0.0.0)",
31
+ "Port=PORT" => "Port to listen on (default: 8080)",
32
+ "Quiet" => "Don't report each request"
33
+ }
34
+ end
35
+ end
36
+
37
+ register :'spider-gazelle', SpiderGazelle
38
+ end
47
39
  end
@@ -1,5 +1,5 @@
1
1
  require 'thread'
2
- require 'radix'
2
+ require 'radix/base'
3
3
 
4
4
 
5
5
  module SpiderGazelle
@@ -14,11 +14,13 @@ module SpiderGazelle
14
14
  @loaded = ThreadSafe::Cache.new
15
15
 
16
16
  # Load an app and assign it an ID
17
- def self.load(rackup)
18
- id = @loaded[rackup.to_sym]
17
+ def self.load(app, options={})
18
+ is_rack_app = !app.is_a?(String)
19
+ app_key = is_rack_app ? app.class.name.to_sym : app.to_sym
20
+ id = @loaded[app_key]
19
21
 
20
22
  if id.nil?
21
- app, options = ::Rack::Builder.parse_file rackup
23
+ app, options = ::Rack::Builder.parse_file(app) unless is_rack_app
22
24
 
23
25
  count = 0
24
26
  @mutex.synchronize {
@@ -26,7 +28,7 @@ module SpiderGazelle
26
28
  }
27
29
  id = Radix.convert(count, B10, B65).to_sym
28
30
  @apps[id] = app
29
- @loaded[rackup.to_sym] = id
31
+ @loaded[app_key] = id
30
32
  end
31
33
 
32
34
  id
@@ -5,8 +5,8 @@ require 'set'
5
5
  module SpiderGazelle
6
6
  class Binding
7
7
  DEFAULT_OPTIONS = {
8
- :host => '0.0.0.0',
9
- :port => 3000,
8
+ :Host => '0.0.0.0',
9
+ :Port => 3000,
10
10
  :tls => false,
11
11
  :optimize_for_latency => true,
12
12
  :backlog => 1024
@@ -21,7 +21,7 @@ module SpiderGazelle
21
21
  @options = DEFAULT_OPTIONS.merge(options)
22
22
  @loop = loop
23
23
  @delegate = delegate
24
- @port = @options[:port]
24
+ @port = @options[:Port]
25
25
  @tls = @options[:tls]
26
26
  @optimize = @options[:optimize_for_latency]
27
27
 
@@ -34,7 +34,7 @@ module SpiderGazelle
34
34
  def bind
35
35
  # Bind the socket
36
36
  @tcp = @loop.tcp
37
- @tcp.bind(@options[:host], @port, @new_connection)
37
+ @tcp.bind(@options[:Host], @port, @new_connection)
38
38
  @tcp.listen(@options[:backlog])
39
39
 
40
40
  # Delegate errors
@@ -197,8 +197,6 @@ module SpiderGazelle
197
197
 
198
198
  # If a file, stream the body in a non-blocking fashion
199
199
  if body.respond_to? :to_path
200
- headers[CONNECTION] = CLOSE if @request.keep_alive == false
201
-
202
200
  if headers[CONTENT_LENGTH]
203
201
  type = :raw
204
202
  else
@@ -250,8 +248,6 @@ module SpiderGazelle
250
248
  end
251
249
 
252
250
  def write_response(status, headers, body)
253
- headers[CONNECTION] = CLOSE if @request.keep_alive == false
254
-
255
251
  if headers[CONTENT_LENGTH]
256
252
  headers[CONTENT_LENGTH] = headers[CONTENT_LENGTH].to_s
257
253
  write_headers(status, headers)
@@ -282,6 +278,8 @@ module SpiderGazelle
282
278
  end
283
279
 
284
280
  def write_headers(status, headers)
281
+ headers[CONNECTION] = CLOSE if @request.keep_alive == false
282
+
285
283
  header = "HTTP/1.1 #{status} #{fetch_code(status)}\r\n"
286
284
  headers.each do |key, value|
287
285
  next if key.start_with? RACK
@@ -87,6 +87,8 @@ module SpiderGazelle
87
87
  @env.delete(HTTP_CONNECTION)
88
88
 
89
89
  @env[REQUEST_URI] = @url.freeze
90
+ # For Rack::Lint on 1.9, ensure that the encoding is always for spec
91
+ @body.force_encoding('ASCII-8BIT') if @body.respond_to?(:force_encoding)
90
92
  @env[RACK_INPUT] = StringIO.new(@body)
91
93
 
92
94
  # Break the request into its components
@@ -99,6 +101,7 @@ module SpiderGazelle
99
101
  else
100
102
  @env[PATH_INFO] = @url
101
103
  @env[REQUEST_PATH] = @url
104
+ @env[QUERY_STRING] = ''
102
105
  end
103
106
 
104
107
  # Grab the host name from the request
@@ -17,6 +17,11 @@ module SpiderGazelle
17
17
  STATES = [:reanimating, :running, :squashing, :dead]
18
18
  MODES = [:thread, :process, :no_ipc] # TODO:: implement clustering using processes
19
19
 
20
+ DEFAULT_OPTIONS = {
21
+ :Host => '0.0.0.0',
22
+ :Port => 8080,
23
+ :Verbose => false
24
+ }
20
25
 
21
26
  attr_reader :state, :mode, :threads, :logger
22
27
 
@@ -66,6 +71,42 @@ module SpiderGazelle
66
71
  end
67
72
  end
68
73
 
74
+ def run(&block)
75
+ @web.run &block
76
+ end
77
+
78
+ def self.run(app, options = {})
79
+ options = DEFAULT_OPTIONS.merge(options)
80
+
81
+ instance.run do |logger|
82
+ logger.progress do |level, errorid, error|
83
+ begin
84
+ puts "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
85
+ rescue Exception
86
+ p 'error in gazelle logger'
87
+ end
88
+ end
89
+
90
+ puts "Look out! Here comes Spider-Gazelle #{::SpiderGazelle::VERSION}!"
91
+ puts "* Environment: #{ENV['RACK_ENV']} on #{RUBY_ENGINE || 'ruby'} #{RUBY_VERSION}"
92
+ server = ::SpiderGazelle::Spider.instance
93
+ server.loaded.then do
94
+ puts "* Loading: #{app}"
95
+
96
+ # yield server if block_given?
97
+
98
+ server.load(app, options).catch(proc {|e|
99
+ puts "#{e.message}\n#{e.backtrace.join("\n") unless e.backtrace.nil?}\n"
100
+ }).finally do
101
+ # This will execute if the TCP binding is lost
102
+ server.shutdown
103
+ end
104
+
105
+ puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
106
+ end
107
+ end
108
+ end
109
+
69
110
  # Provides a promise that resolves when we are read to start binding applications
70
111
  #
71
112
  # @return [::Libuv::Q::Promise] that indicates when the gazelles are loaded
@@ -1,10 +1,11 @@
1
1
  require 'websocket/driver'
2
+ require 'forwardable'
2
3
 
3
4
 
4
5
  module SpiderGazelle
5
6
  # TODO:: make a promise that resolves when closed
6
7
  class Websocket < ::Libuv::Q::DeferredPromise
7
- attr_reader :env, :url, :driver, :socket
8
+ attr_reader :env, :url, :loop
8
9
 
9
10
 
10
11
  def initialize(tcp, env)
@@ -29,10 +30,15 @@ module SpiderGazelle
29
30
  @driver.on(:error, &method(:on_error))
30
31
  end
31
32
 
32
- def start
33
- @driver.start
34
- end
35
33
 
34
+ extend Forwardable
35
+ def_delegators :@driver, :start, :ping, :protocol, :ready_state, :set_header, :state, :close
36
+ def_delegators :@socket, :write
37
+
38
+
39
+ # Write some text to the websocket connection
40
+ #
41
+ # @param string [String] a string of data to be sent to the far end
36
42
  def text(string)
37
43
  data = string.to_s
38
44
  @loop.schedule do
@@ -40,6 +46,9 @@ module SpiderGazelle
40
46
  end
41
47
  end
42
48
 
49
+ # Write some binary data to the websocket connection
50
+ #
51
+ # @param array [Array] an array of bytes to be sent to the far end
43
52
  def binary(array)
44
53
  data = array.to_a
45
54
  @loop.schedule do
@@ -47,13 +56,20 @@ module SpiderGazelle
47
56
  end
48
57
  end
49
58
 
59
+ # Used to define a callback when data is received from the client
60
+ #
61
+ # @param callback [Proc] the callback to be called when data is received
50
62
  def progress(callback = nil, &blk)
51
63
  @progress = callback || blk
52
64
  end
53
65
 
54
-
55
- def write(data)
56
- @socket.write(data)
66
+ # Used to define a callback when the websocket connection is established
67
+ # Data sent before this callback is buffered.
68
+ #
69
+ # @param callback [Proc] the callback to be triggered on establishment
70
+ def on_open(callback = nil, &blk)
71
+ callback ||= blk
72
+ @driver.on(:open, &callback)
57
73
  end
58
74
 
59
75
 
@@ -1,3 +1,3 @@
1
1
  module SpiderGazelle
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  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: 0.1.2
4
+ version: 0.1.3
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: 2014-01-19 00:00:00.000000000 Z
11
+ date: 2014-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake