Class: FDK::Listener

Inherits:
Object
  • Object
show all
Defined in:
lib/fdk/listener.rb

Overview

Represents the socket that Fn uses to communicate with the FDK (and thence the function) To avoid Fn trying to connect to the socket before it’s ready, the Listener creates a socket on (private_socket_path).

When the socket is ready to accept connections, the FDK links the private_socket_path to the socket_path.

Fn waits for the socket_path to be created and then connects

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url:) ⇒ Listener

Returns a new instance of Listener.

[View source]

32
33
34
35
36
37
38
39
40
41
42
# File 'lib/fdk/listener.rb', line 32

def initialize(url:)
  if url.nil? || !url.start_with?("unix:/")
    raise "Missing or invalid socket URL in FN_LISTENER."
  end

  @fn_logframe_name = ENV["FN_LOGFRAME_NAME"]
  @fn_logframe_hdr = ENV["FN_LOGFRAME_HDR"]

  @url = url
  @private_socket = UNIXServer.open(private_socket_path)
end

Instance Attribute Details

#fn_logframe_hdrObject (readonly)

Returns the value of attribute fn_logframe_hdr.


30
31
32
# File 'lib/fdk/listener.rb', line 30

def fn_logframe_hdr
  @fn_logframe_hdr
end

#fn_logframe_nameObject (readonly)

Returns the value of attribute fn_logframe_name.


30
31
32
# File 'lib/fdk/listener.rb', line 30

def fn_logframe_name
  @fn_logframe_name
end

#private_socketObject (readonly)

Returns the value of attribute private_socket.


30
31
32
# File 'lib/fdk/listener.rb', line 30

def private_socket
  @private_socket
end

#urlObject (readonly)

Returns the value of attribute url.


30
31
32
# File 'lib/fdk/listener.rb', line 30

def url
  @url
end

Instance Method Details

#handle_request(fn_block:) ⇒ Object

[View source]

68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/fdk/listener.rb', line 68

def handle_request(fn_block:)
  local_socket = socket.accept
  req, resp = new_req_resp
  req.parse(local_socket)
  FDK.debug "got request #{req}"
  log_frame_header(req.header)
  fn_block.call(req, resp)
  resp["Connection"] = "close" # we're not using keep alives sadly
  resp.send_response(local_socket)
  FDK.debug "sending resp  #{resp.status}, #{resp.header}"
  local_socket.close
end
[View source]

49
50
51
52
53
# File 'lib/fdk/listener.rb', line 49

def link_socket_file
  File.chmod(0o666, private_socket_path)
  FileUtils.ln_s(File.basename(private_socket_path), socket_path)
  FDK.debug "listening on #{private_socket_path}->#{socket_path}"
end

#listen(&block) ⇒ Object

[View source]

55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/fdk/listener.rb', line 55

def listen(&block)
  raise StandardError("No block given") unless block_given?

  begin
    loop do
      handle_request(fn_block: block)
    end
  rescue StandardError => e
    FDK.log(entry: "Error in request handling #{e}")
    FDK.log(entry: e.backtrace)
  end
end

#log_frame_header(headers) ⇒ Object

[View source]

95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/fdk/listener.rb', line 95

def log_frame_header(headers)
  return unless logframe_vars_exist

  k = @fn_logframe_hdr.downcase
  v = headers[k]
  return if v.nil? || v.empty?

  frm = "\n#{@fn_logframe_name}=#{v[0]}\n"
  $stderr.print frm
  $stderr.flush
  $stdout.print frm
  $stdout.flush
end

#logframe_vars_existObject

[View source]

109
110
111
112
113
114
# File 'lib/fdk/listener.rb', line 109

def logframe_vars_exist
  return false if @fn_logframe_name.nil? || @fn_logframe_name.empty? ||
                  @fn_logframe_hdr.nil? || @fn_logframe_hdr.empty?

  true
end

#new_req_respObject

[View source]

81
82
83
84
85
# File 'lib/fdk/listener.rb', line 81

def new_req_resp
  req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  resp = WEBrick::HTTPResponse.new(WEBrick::Config::HTTP)
  [req, resp]
end

#private_socket_pathObject

[View source]

91
92
93
# File 'lib/fdk/listener.rb', line 91

def private_socket_path
  "#{socket_path}.private"
end

#socketObject

[View source]

44
45
46
47
# File 'lib/fdk/listener.rb', line 44

def socket
  link_socket_file unless @socket
  @socket ||= private_socket
end

#socket_pathObject

[View source]

87
88
89
# File 'lib/fdk/listener.rb', line 87

def socket_path
  @socket_path ||= url[5..url.length]
end