reloadCommand returns an entrypoint that convinces PgBouncer to reload configuration files. The process will appear as name in `ps` and `top`.
(name string)
| 243 | // reloadCommand returns an entrypoint that convinces PgBouncer to reload |
| 244 | // configuration files. The process will appear as name in `ps` and `top`. |
| 245 | func reloadCommand(name string) []string { |
| 246 | // Use a Bash loop to periodically check the mtime of the mounted |
| 247 | // configuration volume. When it changes, signal PgBouncer and print the |
| 248 | // observed timestamp. |
| 249 | // |
| 250 | // Coreutils `sleep` uses a lot of memory, so the following opens a file |
| 251 | // descriptor and uses the timeout of the builtin `read` to wait. That same |
| 252 | // descriptor gets closed and reopened to use the builtin `[ -nt` to check |
| 253 | // mtimes. |
| 254 | // - https://unix.stackexchange.com/a/407383 |
| 255 | const script = ` |
| 256 | exec {fd}<> <(:||:) |
| 257 | while read -r -t 5 -u "${fd}" ||:; do |
| 258 | if [[ "${directory}" -nt "/proc/self/fd/${fd}" ]] && pkill -HUP --exact pgbouncer |
| 259 | then |
| 260 | exec {fd}>&- && exec {fd}<> <(:||:) |
| 261 | stat --format='Loaded configuration dated %y' "${directory}" |
| 262 | fi |
| 263 | done |
| 264 | ` |
| 265 | |
| 266 | // Elide the above script from `ps` and `top` by wrapping it in a function |
| 267 | // and calling that. |
| 268 | wrapper := `monitor() {` + script + `}; export directory="$1"; export -f monitor; exec -a "$0" bash -ceu monitor` |
| 269 | |
| 270 | return []string{"bash", "-ceu", "--", wrapper, name, configDirectory} |
| 271 | } |
no outgoing calls