Skip to content

Commit b1e6558

Browse files
committed
Hard won improvements
* Sleep for 5 seconds on update to ensure queue has finished restarting and that supervisord has actually stopped * Use correct user to start workers -- don't use sudo in command and instead specify webapp user * Make queue option optional based on queue_driver (beanstalk or no) * Supply environment variables via supervisord for a cleaner experience * Pass vars to program building method to the environment parameter as key-value IE KEY1="value1" * Quote values if they are not alphanumeric * Remove step in deploy script to copy env vars to .env file
1 parent 55612e4 commit b1e6558

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,17 @@ IS_WORKER = true
6262

6363
### Set Queue Driver
6464

65-
Set the [driver](https://laravel.com/docs/5.1/queues#introduction) in your your EB envronmental variables:
65+
Set the [driver](https://laravel.com/docs/5.1/queues#introduction) in your your EB environmental variables:
6666

6767
```
6868
QUEUE_DRIVER = [driver]
6969
```
7070

71-
**Note: If no `QUEUE_DRIVER` key is present in your EB envronmental variables then `beanstalkd` will be used.**
71+
**Note: If no `QUEUE_DRIVER` key is present in your EB environmental variables then `beanstalkd` will be used.**
7272

7373
### Add Queues
7474

75-
All queues are configured using EB envronmental variables with the following syntax:
75+
All queues are configured using EB environmental variables with the following syntax:
7676

7777
**Note**: brackets are placeholders only, do not use them in your actual configuration
7878

@@ -131,17 +131,19 @@ Supervisor requires port 9001 to be open if you want to access its web monitor.
131131

132132
`parseConfig.php` looks for either a user-supplied `supervisord.conf` file specified in configuration. If one exists then it is used.
133133

134-
Otherwise `parseConfig.php` looks for a json file generated earlier that contains all of the environmental variables configured for elastic beanstalk. It then parses out any queue configurations found (see `Add Queues`) section above and generates a supervisor program for each. The program to be generated looks like this:
134+
Otherwise `parseConfig.php` looks for a json file generated earlier that contains all of the environmental variables configured for elastic beanstalk. It then parses out any queue configurations found (see `Add Queues`) section above and generates a supervisor program for each as well as supplying each program with all the environmental variables set for EB. The program to be generated looks like this:
135135

136136
```
137137
[program:$queue]
138-
command=sudo php artisan queue:work $connection --queue=$queue --tries=$tries --sleep=$sleep --daemon
138+
command=php artisan queue:work $connection --queue=$queue --tries=$tries --sleep=$sleep --daemon
139139
directory=/var/app/current/
140140
autostart=true
141141
autorestart=true
142142
process_name=$queue-%(process_num)s
143143
numprocs=$numProcs
144144
startsecs=$startSecs
145+
user=webapp
146+
environment=$environmentVal
145147
```
146148

147149
After parsing all queues it then appends the programs to a clean `supervisord.conf` file in the same directory.
@@ -169,7 +171,6 @@ Now a bash script `workerDeploy.sh` checks for `IS_WORKER=TRUE` in the EB enviro
169171
This is almost verbatim how I have things setup for another project so some usage is limited because of how it was originally written:
170172

171173
* Queue driver defaults to beanstalkd if not explicitly set
172-
* There is no way to generate a supervisor program without `--queue=[queue]` right now
173174

174175
All of these are simple fixes though! Check out issues to see these and more and if you need them please make a PR!
175176

src/.ebextensions/parseConfig.php

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
<?php
22

3-
function generateProgram($connection, $queue, $tries, $sleep, $numProcs, $delay, $startSecs)
3+
function generateProgram($connection, $queue, $tries, $sleep, $numProcs, $delay, $startSecs, $environmentVal)
44
{
5+
$queueVal = $queue !== null ? " --queue=$queue ": '';
56
$program = <<<EOT
67
78
[program:$queue]
8-
command=sudo php artisan queue:work $connection --queue=$queue --tries=$tries --sleep=$sleep --delay=$delay --daemon
9+
process_name=%(program_name)s_%(process_num)02d
10+
command=php artisan queue:work $connection$queueVal--tries=$tries --sleep=$sleep --delay=$delay --daemon
911
directory=/var/app/current/
1012
autostart=true
1113
autorestart=true
12-
process_name=$queue-%(process_num)s
1314
numprocs=$numProcs
1415
startsecs=$startSecs
16+
user=webapp
17+
environment=$environmentVal
1518
1619
EOT;
1720

@@ -101,13 +104,28 @@ function getEBWorkerConfig($path)
101104
echo 'No user-supplied supervisord.conf found. Generating one from environmental variables.' . PHP_EOL;
102105
}
103106

104-
$envLocation = $deployDirectory . '/jsonEnv';
105-
$vars = json_decode(file_get_contents($envLocation), true);
106-
$envVars = array_change_key_case($vars); // convert keys to lower case so environmental variables don't have to be case-sensitive
107+
$envLocation = $deployDirectory . '/jsonEnv';
108+
$envVars = json_decode(file_get_contents($envLocation), true);
109+
$lowerEnvVars = array_change_key_case($envVars); // convert keys to lower case so environmental variables don't have to be case-sensitive
110+
111+
$envKvArray = [];
112+
foreach ($envVars as $key => $val) {
113+
if(ctype_alnum($val) // alphanumeric doesn't need quotes
114+
|| (strpos($val, '"') === 0 && strrpos($val, '"') === count($val) -1)) // if the value is already quoted don't double-quote it
115+
{
116+
$formattedVal = $val;
117+
} else { // otherwise put everything in quotes for environment param http://supervisord.org/configuration.html#program-x-section-values
118+
$formattedVal = "\"{$val}\"";
119+
}
120+
$envKvArray[] = "{$key}={$formattedVal}";
121+
}
122+
$envKv = implode(',', $envKvArray);
107123

108124
$programs = '';
109125

110-
foreach ($envVars as $key => $val)
126+
$isBeanstalk = $lowerEnvVars['queue_driver'] === 'beanstalkd';
127+
128+
foreach ($lowerEnvVars as $key => $val)
111129
{
112130
if (strpos($key, 'queue') !== false && strpos($key, 'queue_driver') === false)
113131
{
@@ -117,13 +135,19 @@ function getEBWorkerConfig($path)
117135
$startSecsKey = substr($key, 5) . 'startsecs'; //get queue $key + number of seconds the process should stay up
118136
$delayKey = substr($key, 5) . 'delay'; //get queue $key + delay in seconds before a job should re-enter the ready queue
119137

120-
$tries = isset($envVars[ $tryKey ]) ? $envVars[ $tryKey ] : 5;
121-
$sleep = isset($envVars[ $sleepKey ]) ? $envVars[ $sleepKey ] : 5;
122-
$numProcs = isset($envVars[ $numProcKey ]) ? $envVars[ $numProcKey ] : 1;
123-
$startSecs = isset($envVars[ $startSecsKey ]) ? $envVars[ $startSecsKey ] : 1;
124-
$delay = isset($envVars[ $delayKey]) ? $envVars[ $delayKey ] : 0;
125-
$connection = isset($envVars['queue_driver']) ? $envVars['queue_driver'] : 'beanstalkd';
126-
$programs .= generateProgram($connection, $val, $tries, $sleep, $numProcs, $delay, $startSecs);
138+
$tries = isset($lowerEnvVars[ $tryKey ]) ? $lowerEnvVars[ $tryKey ] : 5;
139+
$sleep = isset($lowerEnvVars[ $sleepKey ]) ? $lowerEnvVars[ $sleepKey ] : 5;
140+
$numProcs = isset($lowerEnvVars[ $numProcKey ]) ? $lowerEnvVars[ $numProcKey ] : 1;
141+
$startSecs = isset($lowerEnvVars[ $startSecsKey ]) ? $lowerEnvVars[ $startSecsKey ] : 1;
142+
$delay = isset($lowerEnvVars[ $delayKey ]) ? $lowerEnvVars[ $delayKey ] : 0;
143+
// if using beanstalk connection should always be beanstalkd and specify tube in queue, otherwise us queue name as connection
144+
$connection = $isBeanstalk ? 'beanstalkd' : $val;
145+
// if not using beanstalk we don't need queue probably
146+
$queue = $isBeanstalk ? $val : null;
147+
$programEnvArray = $envKvArray;
148+
// if any vars need to be specific per worker this is where to put them
149+
// $programEnvArray[] =
150+
$programs .= generateProgram($connection, $queue, $tries, $sleep, $numProcs, $delay, $startSecs, implode(',', $programEnvArray));
127151
}
128152
}
129153
}

src/.ebextensions/workerDeploy.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ updateSupervisor(){
88
cp .ebextensions/supervisord.conf /etc/supervisord.conf
99
sudo service supervisord stop
1010
php /var/app/current/artisan queue:restart # If this worker is running in daemon mode (most likely) we need to restart it with the new build
11+
echo "Sleeping a few seconds to make sure supervisor shuts down..." # https://github.com/Supervisor/supervisor/issues/48#issuecomment-2684400
12+
sleep 5
1113
sudo service supervisord start
1214
}
1315

@@ -42,8 +44,6 @@ if test "${ary['IS_WORKER']+isset}" #if key exists
4244
if [ ${ary['IS_WORKER']} == "'true'" ] #if the value is true
4345
then
4446
echo "Found worker key!"
45-
echo "Copying environmental variables to dotenv"
46-
cp bashEnv .env
4747
echo "Starting worker deploy process...";
4848

4949
if [ -f /etc/init.d/supervisord ];

0 commit comments

Comments
 (0)