fastly 0.12.0

Fastly Compute API
Documentation
//! Functions for interacting with the runtime of the Compute service.
//!

use fastly_shared::FastlyStatus;
use fastly_sys::fastly_compute_runtime::{get_heap_mib, get_vcpu_ms};
#[cfg(not(target_env = "p1"))]
use fastly_sys::service0_1_0::fastly::compute as wit;
use lazy_static::lazy_static;

/// Get the amount of vCPU time that has passed since this instance was started,
/// in milliseconds.
///
/// This function returns only time spent running on a vCPU, and does not include
/// time spent performing any I/O operations. However, it is based on clock time
/// passing, and so will include time spent executing hostcalls, is heavily
/// affected by what core of what CPU is running the code, and can even be
/// influenced by the state of the CPU.
///
/// As a result, this function *should not be used in benchmarking across runs*.
/// It can be used, with caution, to compare the runtime of different operations
/// within the same session.
pub fn elapsed_vcpu_ms() -> Result<u64, FastlyStatus> {
    let mut vcpu_time = 0u64;
    let vcpu_time_result = unsafe { get_vcpu_ms(&mut vcpu_time) };
    if vcpu_time_result != FastlyStatus::OK {
        return Err(vcpu_time_result);
    }
    Ok(vcpu_time)
}

/// Get the current dynamic memory usage of this sandbox, rounded up to the nearest mebibyte (2^20
/// bytes).
///
/// The memory accounted includes the WASM linear memory (i.e. heap memory), as well as some memory
/// used by the hosting environment; for instance, HTTP bodies that have been read from a TCP
/// connection, but not read by the WASM program. As such, this function provides only a snapshot
/// in time: the memory usage can change without any action from the WASM program. It can also
/// change across runs, as the Compute platform's memory usage changes. Consider the returned value
/// with these possibilities in mind.
pub fn heap_memory_snapshot_mib() -> Result<u32, FastlyStatus> {
    let mut memory_mib = 0u32;
    let result = unsafe { get_heap_mib(&mut memory_mib) };
    if result != FastlyStatus::OK {
        return Err(result);
    }
    Ok(memory_mib)
}

/// The hostname of the Fastly cache server which is executing the current instance, for
/// example, `cache-jfk1034`.
///
/// Equivalent to the "FASTLY_HOSTNAME" environment variable and to [`server.hostname`] in VCL.
///
/// [`server.hostname`]: https://www.fastly.com/documentation/reference/vcl/variables/server/server-hostname/
pub fn hostname() -> &'static str {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref HOSTNAME: String = std::env::var("FASTLY_HOSTNAME").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref HOSTNAME: String = wit::compute_runtime::get_hostname();
    }

    HOSTNAME.as_str()
}

/// The three-character identifying code of the [Fastly POP] in which the current instance is
/// running.
///
/// Equivalent to the "FASTLY_POP" environment variable and to [`server.datacenter`] in VCL.
///
/// [Fastly POP]: https://www.fastly.com/documentation/guides/concepts/pop/
/// [`server.datacenter`]: https://www.fastly.com/documentation/reference/vcl/variables/server/server-datacenter/
pub fn pop() -> &'static str {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref POP: String = std::env::var("FASTLY_POP").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref POP: String = wit::compute_runtime::get_pop();
    }

    POP.as_str()
}

/// A code representing the general region of the world in which the [Fastly POP] processing the
/// current Compute instance resides.
///
/// Equivalent to the "FASTLY_REGION" environment variable and to [`server.region`] in VCL, and has
/// the same possible values.
///
/// [`server.region`]: https://www.fastly.com/documentation/reference/vcl/variables/server/server-region/
/// [Fastly POP]: https://www.fastly.com/documentation/guides/concepts/pop/
pub fn region() -> &'static str {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref REGION: String = std::env::var("FASTLY_REGION").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref REGION: String = wit::compute_runtime::get_region();
    }

    REGION.as_str()
}

/// The current cache identifier for this Fastly service.
///
/// Equivalent to the "FASTLY_CACHE_GENERATION" environment variable and to [`req.vcl.generation`]
/// in VCL.
///
/// [`req.vcl.generation`]: https://www.fastly.com/documentation/reference/vcl/variables/miscellaneous/req-vcl-generation/
pub fn cache_generation() -> u64 {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref CACHE_GENERATION: u64 = std::env::var("FASTLY_CACHE_GENERATION")
            .unwrap()
            .parse()
            .unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref CACHE_GENERATION: u64 = wit::compute_runtime::get_cache_generation();
    }

    *CACHE_GENERATION
}

/// The customer ID of the Fastly customer account to which the currently executing service
/// belongs.
///
/// Equivalent to the "FASTLY_CUSTOMER_ID" environment variable and to [`req.customer_id`] in VCL.
///
/// [`req.customer_id`]: https://www.fastly.com/documentation/reference/vcl/variables/miscellaneous/req-customer-id/
pub fn customer_id() -> &'static str {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref CUSTOMER_ID: String = std::env::var("FASTLY_CUSTOMER_ID").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref CUSTOMER_ID: String = wit::compute_runtime::get_customer_id();
    }

    CUSTOMER_ID.as_str()
}

/// Whether the request is running in the service's [staging environment].
///
/// `false` for production or `true` for staging.
///
/// Equivalent to the "FASTLY_IS_STAGING" environment variable and to [`fastly.is_staging`] in VCL.
///
/// [`fastly.is_staging`]: https://www.fastly.com/documentation/reference/vcl/variables/miscellaneous/fastly-is-staging/
/// [staging environment]: https://docs.fastly.com/products/staging
pub fn is_staging() -> bool {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref IS_STAGING: bool = match std::env::var("FASTLY_IS_STAGING").unwrap().as_str() {
            "0" => false,
            "1" => true,
            _ => unreachable!(),
        };
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref IS_STAGING: bool = wit::compute_runtime::get_is_staging();
    }

    *IS_STAGING
}

/// The identifier for the Fastly service that is processing the current request.
///
/// Equivalent to the "FASTLY_SERVICE_ID" environment variable and to [`req.service_id`] in VCL.
///
/// [`req.service_id`]: https://www.fastly.com/documentation/reference/vcl/variables/miscellaneous/req-service-id/
pub fn service_id() -> &'static str {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref SERVICE_ID: String = std::env::var("FASTLY_SERVICE_ID").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref SERVICE_ID: String = wit::compute_runtime::get_service_id();
    }

    SERVICE_ID.as_str()
}

/// The version number for the Fastly service that is processing the current request.
///
/// Equivalent to the "FASTLY_SERVICE_VERSION" environment variable and to [`req.vcl.version`]
/// in VCL.
///
/// [`req.vcl.version`]: https://www.fastly.com/documentation/reference/vcl/variables/miscellaneous/req-vcl-version/
pub fn service_version() -> u64 {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref SERVICE_VERSION: u64 = std::env::var("FASTLY_SERVICE_VERSION")
            .unwrap()
            .parse()
            .unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref SERVICE_VERSION: u64 = wit::compute_runtime::get_service_version();
    }

    *SERVICE_VERSION
}

#[doc(hidden)]
pub fn namespace_id() -> &'static str {
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref NAMESPACE_ID: String = std::env::var("FASTLY_NAMESPACE_ID").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref NAMESPACE_ID: String = wit::compute_runtime::get_hostname();
    }

    NAMESPACE_ID.as_str()
}

/// A UUID generated by Fastly for each sandbox.
///
/// This is often a useful value to include in log messages, and also to send to upstream
/// servers as an additional custom HTTP header, allowing for straightforward correlation of
/// which WebAssembly session processed a request to requests later processed by an origin
/// server. If a session is used to process multiple downstream requests, then you may wish to
/// use the per-request UUID associated with each individual request handle instead of this
/// function.
///
/// Equivalent to the "FASTLY_TRACE_ID" environment variable.
pub fn sandbox_id() -> &'static str {
    // There is no `FASTLY_SANDBOX_ID`, however `FASTLY_TRACE_ID` is a
    // per-sandbox identifier.
    #[cfg(target_env = "p1")]
    lazy_static! {
        static ref SANDBOX_ID: String = std::env::var("FASTLY_TRACE_ID").unwrap();
    }

    #[cfg(not(target_env = "p1"))]
    lazy_static! {
        static ref SANDBOX_ID: String = wit::compute_runtime::get_sandbox_id();
    }

    SANDBOX_ID.as_str()
}