Skip to content
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

Gracefully restart running application #188

Open
kinnalru opened this issue Sep 4, 2022 · 8 comments
Open

Gracefully restart running application #188

kinnalru opened this issue Sep 4, 2022 · 8 comments

Comments

@kinnalru
Copy link

kinnalru commented Sep 4, 2022

Hi. I investigate possibility to gracefully restart currently running rails application from inside running instance. Main aim is to restart application after serving certain number of requests (ex. After 4000 requests) or after hitting memory limit.

In Passenger or Puma this is possible from middleware through passenger-config dettach-process $pid or something like this.

I see some methods is async::containers like reload or other but I can't understand how to use them from inside middleware. Is it sufficient to "kill self by INT signal" ?

@ioquatix
Copy link
Member

ioquatix commented Sep 4, 2022

Yes, but that will terminate all current requests handled by that process... try it out and let me know how you get on?

@kinnalru
Copy link
Author

kinnalru commented Sep 5, 2022

Yes, but that will terminate all current requests handled by that process... try it out and let me know how you get on?

I make some experimets... Test server through falcon serve and falcon host
... killing self from inside application (from middleware) kills current request immidiate ...
... falcon supervisor restart stops application I don't understand why ...

But killing through signal HUP whole server works as expected but some requests are broken. Example (2 forks):

  1. starting rails server (without DB just api) by RAILS_ENV=production bundle exec falcon host
# falcon.rb

load :rack, :supervisor

rack 'prober' do
  scheme 'http'
  protocol { Async::HTTP::Protocol::HTTP1 }

  count 2

  endpoint do
    Async::HTTP::Endpoint.for(scheme, '0.0.0.0', port: 3000, protocol: protocol)
  end

end

supervisor
  1. requesting with Yandex Tank 10 rps.
  2. killing with single kill -HUP $PID
  3. ... aplication reloads...
  4. see broken requests :(

Screenshot_20220905_191608

@ioquatix
Copy link
Member

ioquatix commented Sep 5, 2022

Okay let me take a look.

@trevorturk
Copy link
Contributor

trevorturk commented Feb 21, 2023

I believe this is a related issue: #71, and also maybe #22

@ioquatix
Copy link
Member

Sorry, I did not follow up on this, I will take a look today.

@ioquatix
Copy link
Member

I won't get a chance to look at this but I've put it on my planning board.

@trevorturk
Copy link
Contributor

No worries, it's a nice-to-have, but I appreciate your attention in any case!

@kinnalru
Copy link
Author

kinnalru commented Oct 16, 2023

Sometimes when I go back I see this in Service::Supervisor:

	# Restart the process group that the supervisor belongs to.
	def do_restart(message)
		# Tell the parent of this process group to spin up a new process group/container.
		# Wait for that to start accepting new connections.
		# Stop accepting connections.
		# Wait for existing connnections to drain.
		# Terminate this process group.
		signal = message[:signal] || :INT
		
		Process.kill(signal, Process.ppid)
	end

...but there is no such feature in Service::Application :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants