Class: SpiderGazelle::Gazelle

Inherits:
Object
  • Object
show all
Includes:
Const
Defined in:
lib/spider-gazelle/gazelle.rb

Constant Summary

Constants included from Const

Const::ASCII_8BIT, Const::ASYNC, Const::CGI_VER, Const::CHUNKED, Const::CLOSE, Const::CLOSE_CHUNKED, Const::COLON, Const::COLON_SPACE, Const::COMMA, Const::CONNECTION, Const::CONTENT_LENGTH, Const::CONTENT_LENGTH2, Const::CONTENT_TYPE, Const::DASH, Const::DEFAULT_TYPE, Const::EMPTY, Const::ERROR_400_RESPONSE, Const::ERROR_404_RESPONSE, Const::ERROR_408_RESPONSE, Const::ERROR_500_RESPONSE, Const::ERROR_503_RESPONSE, Const::GATEWAY_INTERFACE, Const::HEAD, Const::HEX_SIZE_CHUNKED_RESPONSE, Const::HIJACK, Const::HIJACK_IO, Const::HIJACK_P, Const::HTTP, Const::HTTPS, Const::HTTP_11, Const::HTTP_CONTENT_LENGTH, Const::HTTP_CONTENT_TYPE, Const::HTTP_HOST, Const::HTTP_META, Const::HTTP_STATUS_DEFAULT, Const::INTERNAL_PIPE_BACKLOG, Const::KEEP_ALIVE, Const::KILL_GAZELLE, Const::LINE_END, Const::LOCALHOST, Const::NEWLINE, Const::NO_TLS, Const::PATH_INFO, Const::PORT_443, Const::PORT_80, Const::QUERY_STRING, Const::QUESTION_MARK, Const::RACK, Const::RACK_ERRORS, Const::RACK_INPUT, Const::RACK_MULTIPROCESS, Const::RACK_MULTITHREAD, Const::RACK_RUN_ONCE, Const::RACK_URL_SCHEME, Const::RACK_VERSION, Const::REMOTE_ADDR, Const::REQUEST_METHOD, Const::REQUEST_PATH, Const::REQUEST_URI, Const::SCRIPT_NAME, Const::SERVER, Const::SERVER_NAME, Const::SERVER_PORT, Const::SERVER_PROTOCOL, Const::SERVER_SOFTWARE, Const::SPACE, Const::SPIDER_GAZELLE_VERSION, Const::TRANSFER_ENCODING, Const::UNDERSCORE, Const::USE_TLS, Const::ZERO

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(loop, logger, mode) ⇒ Gazelle

Returns a new instance of Gazelle.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/spider-gazelle/gazelle.rb', line 14

def initialize(loop, logger, mode)
  @gazelle = loop
  # Set of active connections on this thread
  @connections = Set.new
  # Stale parser objects cached for reuse
  @parser_cache = []

  @mode = mode
  @logger = logger
  @app_cache = {}
  @connection_queue = ::Libuv::Q::ResolvedPromise.new @gazelle, true

  # A single parser instance for processing requests for each gazelle
  @parser = ::HttpParser::Parser.new self
  @set_instance_type = method :set_instance_type

  # Single progress callback for each gazelle
  @on_progress = method :on_progress
end

Instance Attribute Details

#connectionsObject (readonly)

Returns the value of attribute connections.



8
9
10
# File 'lib/spider-gazelle/gazelle.rb', line 8

def connections
  @connections
end

#loggerObject (readonly)

Returns the value of attribute logger.



8
9
10
# File 'lib/spider-gazelle/gazelle.rb', line 8

def logger
  @logger
end

#parser_cacheObject (readonly)

Returns the value of attribute parser_cache.



8
9
10
# File 'lib/spider-gazelle/gazelle.rb', line 8

def parser_cache
  @parser_cache
end

Instance Method Details

#discard(connection) ⇒ Object



108
109
110
111
112
113
# File 'lib/spider-gazelle/gazelle.rb', line 108

def discard(connection)
  @connections.delete(connection)
  state = connection.state
  state.reset!
  @parser_cache << state
end

#on_body(parser, data) ⇒ Object



100
101
102
# File 'lib/spider-gazelle/gazelle.rb', line 100

def on_body(parser, data)
  @connection.parsing.body << data
end

#on_header_field(parser, header) ⇒ Object



72
73
74
75
# File 'lib/spider-gazelle/gazelle.rb', line 72

def on_header_field(parser, header)
  req = @connection.parsing
  req.header.frozen? ? req.header = header : req.header << header
end

#on_header_value(parser, value) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/spider-gazelle/gazelle.rb', line 77

def on_header_value(parser, value)
  req = @connection.parsing
  if req.header.frozen?
    req.env[req.header] << value
  else
    header = req.header
    header.upcase!
    header.gsub!(DASH, UNDERSCORE)
    header.prepend(HTTP_META)
    header.freeze
    if req.env[header]
      req.env[header] << COMMA
      req.env[header] << value
    else
      req.env[header] = value
    end
  end
end

#on_headers_complete(parser) ⇒ Object



96
97
98
# File 'lib/spider-gazelle/gazelle.rb', line 96

def on_headers_complete(parser)
  @connection.parsing.env[REQUEST_METHOD] = @connection.state.http_method.to_s
end

#on_message_begin(parser) ⇒ Object

HTTP Parser callbacks:



64
65
66
# File 'lib/spider-gazelle/gazelle.rb', line 64

def on_message_begin(parser)
  @connection.start_parsing
end

#on_message_complete(parser) ⇒ Object



104
105
106
# File 'lib/spider-gazelle/gazelle.rb', line 104

def on_message_complete(parser)
  @connection.finished_parsing
end

#on_url(parser, url) ⇒ Object



68
69
70
# File 'lib/spider-gazelle/gazelle.rb', line 68

def on_url(parser, url)
  @connection.parsing.url << url
end

#runObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/spider-gazelle/gazelle.rb', line 34

def run
  @gazelle.run do |logger|
    logger.progress do |level, errorid, error|
      begin
        msg = "Gazelle log: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
        @logger.error msg
      rescue Exception
        puts 'error in gazelle logger'
      end
    end

    unless @mode == :no_ipc
      # A pipe used to forward connections to different threads
      @socket_server = @gazelle.pipe true
      @socket_server.connect(DELEGATE_PIPE) do
        @socket_server.progress &method(:new_connection)
        @socket_server.start_read
      end

      # A pipe used to signal various control commands (shutdown, etc)
      @signal_server = @gazelle.pipe
      @signal_server.connect(SIGNAL_PIPE) do
        @signal_server.progress &method(:process_signal)
        @signal_server.start_read
      end
    end
  end
end

#set_instance_type(inst) ⇒ Object



10
11
12
# File 'lib/spider-gazelle/gazelle.rb', line 10

def set_instance_type(inst)
  inst.type = :request
end