LCOV - code coverage report
Current view: top level - compute_tools/src - local_proxy.rs (source / functions) Coverage Total Hit
Test: 8b13a09a5c233d98abd4a0d3e59157e7db16d6fd.info Lines: 0.0 % 34 0
Test Date: 2024-11-21 10:53:51 Functions: 0.0 % 4 0

            Line data    Source code
       1              : //! Local Proxy is a feature of our BaaS Neon Authorize project.
       2              : //!
       3              : //! Local Proxy validates JWTs and manages the pg_session_jwt extension.
       4              : //! It also maintains a connection pool to postgres.
       5              : 
       6              : use anyhow::{Context, Result};
       7              : use camino::Utf8Path;
       8              : use compute_api::spec::LocalProxySpec;
       9              : use nix::sys::signal::Signal;
      10              : use utils::pid_file::{self, PidFileRead};
      11              : 
      12            0 : pub fn configure(local_proxy: &LocalProxySpec) -> Result<()> {
      13            0 :     write_local_proxy_conf("/etc/local_proxy/config.json".as_ref(), local_proxy)?;
      14            0 :     notify_local_proxy("/etc/local_proxy/pid".as_ref())?;
      15              : 
      16            0 :     Ok(())
      17            0 : }
      18              : 
      19              : /// Create or completely rewrite configuration file specified by `path`
      20            0 : fn write_local_proxy_conf(path: &Utf8Path, local_proxy: &LocalProxySpec) -> Result<()> {
      21            0 :     let config =
      22            0 :         serde_json::to_string_pretty(local_proxy).context("serializing LocalProxySpec to json")?;
      23            0 :     std::fs::write(path, config).with_context(|| format!("writing {path}"))?;
      24              : 
      25            0 :     Ok(())
      26            0 : }
      27              : 
      28              : /// Notify local proxy about a new config file.
      29            0 : fn notify_local_proxy(path: &Utf8Path) -> Result<()> {
      30            0 :     match pid_file::read(path)? {
      31              :         // if the file doesn't exist, or isn't locked, local_proxy isn't running
      32              :         // and will naturally pick up our config later
      33            0 :         PidFileRead::NotExist | PidFileRead::NotHeldByAnyProcess(_) => {}
      34            0 :         PidFileRead::LockedByOtherProcess(pid) => {
      35            0 :             // From the pid_file docs:
      36            0 :             //
      37            0 :             // > 1. The other process might exit at any time, turning the given PID stale.
      38            0 :             // > 2. There is a small window in which `claim_for_current_process` has already
      39            0 :             // >    locked the file but not yet updates its contents. [`read`] will return
      40            0 :             // >    this variant here, but with the old file contents, i.e., a stale PID.
      41            0 :             // >
      42            0 :             // > The kernel is free to recycle PID once it has been `wait(2)`ed upon by
      43            0 :             // > its creator. Thus, acting upon a stale PID, e.g., by issuing a `kill`
      44            0 :             // > system call on it, bears the risk of killing an unrelated process.
      45            0 :             // > This is an inherent limitation of using pidfiles.
      46            0 :             // > The only race-free solution is to have a supervisor-process with a lifetime
      47            0 :             // > that exceeds that of all of its child-processes (e.g., `runit`, `supervisord`).
      48            0 :             //
      49            0 :             // This is an ok risk as we only send a SIGHUP which likely won't actually
      50            0 :             // kill the process, only reload config.
      51            0 :             nix::sys::signal::kill(pid, Signal::SIGHUP).context("sending signal to local_proxy")?;
      52              :         }
      53              :     }
      54              : 
      55            0 :     Ok(())
      56            0 : }
        

Generated by: LCOV version 2.1-beta