rust-prometheus icon indicating copy to clipboard operation
rust-prometheus copied to clipboard

Replace lazy static initializers with const fn

Open brson opened this issue 6 years ago • 7 comments
trafficstars

Should be possible after upgrading to 2018 re https://github.com/pingcap/rust-prometheus/issues/217#issuecomment-453303909

lazy_static! {
    static ref TIKV_REQUEST_DURATION_HISTOGRAM_VEC: HistogramVec = register_histogram_vec!(
        "tikv_request_duration_seconds",
        "Bucketed histogram of TiKV requests duration",
        &["type"]
    )
}

brson avatar Jan 29 '19 18:01 brson

I peeked at the details of this task briefly and it does not look so simple; certainly not as simple as converting (in the above example) register_histogram_vec! to a const fn. That macro invokes plenty of dynamic behavior, like creating Boxes.

@Hoverbear @overvenus do you have an idea of the transformation that needs to be done here?

brson avatar Feb 11 '19 22:02 brson

In this case @breeswish would be a good resource

Hoverbear avatar Feb 12 '19 20:02 Hoverbear

@brson I tried with const fn in 1.0 experiment and looks to be not a good choice currently, due to a lot of std functions necessary in building the metric are not marked as const fn.

breezewish avatar Feb 13 '19 04:02 breezewish

This is problematic. :(

Hoverbear avatar Feb 13 '19 22:02 Hoverbear

A const fn is not going to support the "register" part of register_histogram_vec even after the entire of rust-lang/rust#57563 is implemented, since a const fn cannot mutate something the function doesn't own (the DEFAULT_REGISTRY).

Not using the macro means user would write instead

static TIKV_REQUEST_DURATION_HISTOGRAM_VEC: HistogramVec = HistogramVec::new(
    "tikv_request_duration_seconds",
    "Bucketed histogram of TiKV requests duration",
    &["type"],
);

static SOME_MORE_COLLECTORS: ... = ...;

fn main() -> Result<()> {
    register(Box::new(TIKV_REQUEST_DURATION_HISTOGRAM_VEC.clone())?;
    register(Box::new(SOME_MORE_COLLECTORS.clone())?;  // <-- need to call these manually :(
    ...
}

kennytm avatar Feb 14 '19 00:02 kennytm

Thanks @kennytm ! I think we can wait rust-lang/rust#57563 and then mark as more function as possible to be const fn, but might not be very useful in all cases (as the case kenny illustrated). We can relax the goal of this issue.

Additionally, I would like to mention that the process of registering and creating a metric can be simplified, for example, in 1.0-pre, we can just write:

let counter = CounterBuilder::new("name", "help")
    .build_vec(["a", "b"])
    .unwrap();

breezewish avatar Feb 14 '19 04:02 breezewish

A cleaner alternative is https://docs.rs/once_cell/1.4.0/once_cell/#lazy-initialized-global-data

teohhanhui avatar May 18 '20 18:05 teohhanhui