31

Does anyone know how to find sidekiq's pidfile to gracefully shut it down? Running ps ax | grep sidekiq and then running sidekiqctl stop <pid from grep> consistently gives a no such pidfile error? Cntl-C and Cntl-D also seem to have no effect.

Closing the process window and reopening a new window doesn't kill the process as it appears to be running as a daemon.

The only consistent fix I've found is rebooting.

eebbesen
  • 5,070
  • 8
  • 48
  • 70
user1627827
  • 665
  • 2
  • 7
  • 9

7 Answers7

84

Use this to kill sidekiq forcefully.

ps -ef | grep sidekiq | grep -v grep | awk '{print $2}' | xargs kill -9
Paritosh Piplewar
  • 7,982
  • 5
  • 26
  • 41
  • If one uses `ps -ef | grep sidekiq | grep -v grep | awk '{print $2}' | xargs kill -TERM` sidekiq will give time to pause workers. The `sidekiqctl stop` command is [an abstraction](https://github.com/mperham/sidekiq/blob/master/bin/sidekiqctl#L70) – Francisco Quintero Nov 18 '16 at 21:16
  • Sometimes we dont need to wait, e.g.: testing worker on staging environment, if that's the case, this command should not be used at all – d1jhoni1b Sep 30 '19 at 18:11
37

Sidekiq provides the ability to specify a pidfile at start time or, as shown below, to create the pidfile after the process has been started. In either case you can then use the pidfile at stop time.

  1. Use ps -ef | grep sidekiq to find the pid
  2. Create a file (e.g., sidekiq.pid) with the only contents being the pid you just found
  3. sidekiqctl stop <pidfile_name>
  4. Use -P <pidfile_name> or --pidfile <pidfile_name> when starting sidekiq in the future
eebbesen
  • 5,070
  • 8
  • 48
  • 70
20

Just been looking into this one myself...

Seems like newer versions of Sidekiq have this built in:

https://github.com/mperham/sidekiq/wiki/Signals

kill -USR1 [PROCESS_ID]

Worked great for me. The workers stopped picking up new jobs, but finished the ones they were on, then I finally killed the process when it was done.

kill -TERM [PROCESS_ID]

dazoakley
  • 336
  • 2
  • 4
5

I've written a little handler that can start or stop sidekiq.

start_stop_sidekiq.sh

#!/bin/bash
cmd=$1
PROJECT_DIR=$2
PIDFILE=$PROJECT_DIR/tmp/pids/sidekiq.pid
cd $PROJECT_DIR

start_function(){
  LOGFILE=$PROJECT_DIR/log/sidekiq.log
  echo "Starting sidekiq..."
  bundle exec sidekiq -d -L $LOGFILE -P $PIDFILE -q mailer,5 -q default -e production
}

stop_function(){
  if [ ! -f $PIDFILE ]; then
    ps -ef | grep sidekiq | grep busy | grep -v grep | awk '{print $2}'  > $PIDFILE
  fi
  bundle exec sidekiqctl stop $PIDFILE
}

case "$cmd" in
  start)
    start_function
    ;;
  stop)
    stop_function
    ;;
  restart)
    stop_function && start_function;
    ;;
  *)
    echo $"Usage: $0 {start|stop|restart} /path/to/rails/app"
esac

Save it, type chmod +x start_stop_sidekiq.sh. Then just run it with:

bash start_stop_sidekiq.sh start /path/to/your/rails/app

or

bash start_stop_sidekiq.sh stop /path/to/your/rails/app

If you only have one Rails app, you can also set the $PROJECT_DIR variable statically so that you don't need to specify the path each time. Hope this helps!

DaniG2k
  • 4,772
  • 36
  • 77
2

Try using god to monitor sidekiq.

Then all you need to do is bundle exec god stop

Alternatively, you can use: sidekiqctl stop 60

Henley
  • 21,258
  • 32
  • 119
  • 207
2

If you like bashes...

scripts/stop_sidekiq.sh

#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"

PROJECT_DIR=$DIR/../ # EDIT HERE: rel path to your project form this file location (my scripts are in ./scripts/)
SIDEKIQ_PID_FILE=$PROJECT_DIR/tmp/pids/sidekiq.pid  # EDIT HERE: pid file location

if [ ! -f $SIDEKIQ_PID_FILE ]; then
    # if no pid file, retrieve pid and create file
    ps -ef | grep sidekiq | grep busy | grep -v grep | awk '{print $2}'  > $SIDEKIQ_PID_FILE
fi

(cd $PROJECT_DIR && bundle exec sidekiqctl stop $SIDEKIQ_PID_FILE)

Notes:

  • will work even if sidekiq started without pid file argument
  • assumes this script is in a folder inside the project and pid files are stored in ./tmp/pids/
laffuste
  • 16,287
  • 8
  • 84
  • 91
0

Sharing a bash script that checks if sidekiq is running, sends it TSTP to ask it to not pick up any new jobs, waits until any running jobs are finished and then stops the process by sending a TERM signal to it.

https://gist.github.com/kamilbednarz/5ea6398af2a7537aa8feb5a63f3acf2f

Kamil Bednarz
  • 748
  • 6
  • 9