Skip to content

feat: Support pidfile in CLI & Server (defaults to puma.pid) #178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/functions_framework/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def initialize
@source = ::ENV["FUNCTION_SOURCE"] || ::FunctionsFramework::DEFAULT_SOURCE
@env = nil
@port = nil
@pidfile = nil
@bind = nil
@min_threads = nil
@max_threads = nil
Expand Down Expand Up @@ -67,6 +68,12 @@ def error?
#
attr_reader :error_message

##
# @return [String] The pidfile.
# @return [nil] if not running.
#
attr_reader :pidfile

##
# Parse the given command line arguments.
# Exits if argument parsing failed.
Expand All @@ -89,6 +96,9 @@ def parse_args argv # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
"Supported values are 'http' and 'cloudevent'." do |val|
@signature_type = val
end
op.on "-P", "--pidfile PIDFILE", "Set the pidfile for the server (defaults to puma.pid)" do |val|
@pidfile = val
end
op.on "-p", "--port PORT", "Set the port to listen to (defaults to 8080)" do |val|
@port = val.to_i
end
Expand Down Expand Up @@ -218,6 +228,7 @@ def start_server
::FunctionsFramework.start function do |config|
config.rack_env = @env
config.port = @port
config.pidfile = @pidfile
config.bind_addr = @bind
config.show_error_details = @detailed_errors
config.min_threads = @min_threads
Expand Down
35 changes: 35 additions & 0 deletions lib/functions_framework/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,24 @@ def running?
@server&.thread&.alive?
end

##
# Returns pidfile if server is currently running
#
# @return [String, nil]
#
def pidfile
@config.pidfile if running?
end

##
# Returns whether pidfile is present.
#
# @return [Boolean]
#
def pidfile?
[email protected] && running?
end

##
# Cause this server to respond to SIGTERM, SIGINT, and SIGHUP by shutting
# down gracefully.
Expand Down Expand Up @@ -214,6 +232,7 @@ def initialize
self.rack_env = nil
self.bind_addr = nil
self.port = nil
self.pidfile = nil
self.min_threads = nil
self.max_threads = nil
self.show_error_details = nil
Expand Down Expand Up @@ -245,6 +264,14 @@ def port= port
@port = (port || ::ENV["PORT"] || 8080).to_i
end

##
# Set the pidfile string, or `nil` to use the default.
# @param path [String,nil]
#
def pidfile= path
@pidfile = (path || ::ENV["PIDFILE"] || "puma.pid").to_s
end

##
# Set the minimum number of worker threads, or `nil` to use the default.
# @param min_threads [Integer,nil]
Expand Down Expand Up @@ -306,6 +333,14 @@ def port
@port
end

##
# Returns the current pidfile string.
# @return [String]
#
def pidfile
@pidfile
end

##
# Returns the minimum number of worker threads in the thread pool.
# @return [Integer]
Expand Down
16 changes: 16 additions & 0 deletions test/test_cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
let(:retry_count) { 10 }
let(:retry_interval) { 0.5 }
let(:port) { "8066" }
let(:pidfile) { "server.pid" }
let(:timeout) { 10 }

def run_with_retry cli
Expand Down Expand Up @@ -104,6 +105,21 @@ def run_in_timeout cli
assert_equal "I received a request: GET http://127.0.0.1:#{port}/", response.body
end

it "runs an http server with a pidfile" do
args = [
"--source", http_source,
"--target", "simple_http",
"--port", port,
"--pidfile", pidfile,
"-q"
]
cli = FunctionsFramework::CLI.new.parse_args args
_response = run_with_retry cli do
Net::HTTP.get_response URI("http://127.0.0.1:#{port}/")
end
assert_equal pidfile, cli.pidfile
end

it "runs an http server with a function that includes a return" do
args = [
"--source", http_return_source,
Expand Down
15 changes: 15 additions & 0 deletions test/test_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
end
}
let(:port) { 8077 }
let(:pidfile) { "server.pid" }
let(:server_url) { "http://127.0.0.1:#{port}" }
let(:quiet_logger) {
logger = ::Logger.new $stderr
Expand All @@ -56,6 +57,7 @@ def make_basic_server function, show_error_details: true
config.min_threads = 1
config.max_threads = 1
config.port = port
config.pidfile = pidfile
config.bind_addr = "127.0.0.1"
config.rack_env = "development"
config.logger = quiet_logger
Expand Down Expand Up @@ -94,6 +96,19 @@ def query_server_with_retry server
http_server.stop.wait_until_stopped timeout: 10
end

it "uses a pidfile" do
refute http_server.pidfile?
refute http_server.pidfile
http_server.start
assert http_server.pidfile?
assert http_server.pidfile
http_server.stop.wait_until_stopped timeout: 10
refute http_server.running?
refute http_server.pidfile?
ensure
http_server.stop.wait_until_stopped timeout: 10
end

it "handles post requests" do
response = query_server_with_retry http_server do
::Net::HTTP.post URI("#{server_url}/"), "Hello, world!", "Content-Type" => "text/plain"
Expand Down
Loading