Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly shut down a Mojolicious::Lite server?

In a Mojolicious::Lite app I have a route that I want to kill the server and redirect to another site. Here is the snippet.

my $me = $$;
get '/kill' => sub {
    my $self = shift;
    $self->res->code(301);
    $self->redirect_to('http://www.google.com');
    $self->app->log->debug("Goodbye, $name.");
  
    # I need this function to return so I delay the kill a little.
    system("(sleep 1; kill $me)&");
};

This code does what I want, but it doesn't feel right. I have tried $self->app->stop but that is not available.

Is there a proper technique I should be using to get access to the server?

like image 363
Nicky Avatar asked Mar 20 '23 23:03

Nicky


2 Answers

Update 2021:

This answer was referred to recently in an IRC discussion, so an update is warranted. The response below was a mechanism that I had used in a very specific case. While it may still be useful in rare cases, the more correct manner of stopping a service would be

https://docs.mojolicious.org/Mojo/IOLoop#stop_gracefully or https://docs.mojolicious.org/Mojo/Server/Daemon#SIGNALS for a single-process server or https://docs.mojolicious.org/Mojo/Server/Prefork#MANAGER-SIGNALS for preforking


Original:

There are several ways to do this, of course.

Probably the best, is to simply attach a finish handler to the transaction:

#!/usr/bin/env perl

use Mojolicious::Lite;

get '/kill' => sub {
  my $c = shift;
  $c->redirect_to('http://google.com');
  $c->tx->on( finish => sub { exit } );
};

app->start;

The method most like your example would be to setup a Mojo::IOLoop timer which would wait a few seconds and exit.

#!/usr/bin/env perl

use Mojolicious::Lite;
use Mojo::IOLoop;

get '/kill' => sub {
  my $c = shift;
  $c->redirect_to('http://google.com');
  my $loop = Mojo::IOLoop->singleton;
  $loop->timer( 1 => sub { exit } );
  $loop->start unless $loop->is_running; # portability
};

app->start;
like image 188
Joel Berger Avatar answered Apr 01 '23 13:04

Joel Berger


Joel mentioned Mojo::IOLoop, so here's what I've used for a simple Mojo Lite throwaway app:

get '/shutdown' => sub ($c) {
  $c->render(text => "Shutting down" );
  $c->tx->on( finish => sub { Mojo::IOLoop->stop_gracefully } );
};

Sending signals also works since this is a single process program:

get '/shutdown' => sub ($c) {
  $c->render(text => "Shutting down" );
  $c->tx->on( finish => sub { kill 'TERM', $$ } );
};
like image 29
brian d foy Avatar answered Apr 01 '23 15:04

brian d foy