prometheus / prometheus/client_rust

Abstract key lookup into a trait for Family::get_or_create

Open
#157 4 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
606
Forks
113
Avg merge
9h 7m
Merged PRs (30d)
8

Description

Family::get_or_create forces to clone labels data for the lookup of a counter. Example:

#[derive(Clone, Eq, Hash, PartialEq, EncodeLabelSet)]
struct RequestLabels {
    host: String,
    api: String,
}

fn test() {
    let family = Family::<RequestLabels, Counter>::default();

    fn call(host: &str, api: &str, family: &Family<RequestLabels, Counter>) {
        let labels = RequestLabels {
            host: host.to_string(),
            api: api.to_string(),
        };

        let counter = family.get_or_create(&labels);
        counter.inc();
    }
}

I must create RequestLabels with cloning host and api values instead of getting counter by data references. The Family struct uses the std::collections::HashMap inside, which doesn't allow any other way to look up.

It would be great to have the ability to write something like this:

#[derive(Clone, Eq, Hash, PartialEq, EncodeLabelSet)]
struct RequestLabels {
    host: String,
    api: String,
}

struct RequestLabelsQ<'a> {
    host: &'a str,
    api: &'a str,
}

impl Equivalent<RequestLabels> for RequestLabelsQ<'_> {
    fn equivalent(&self, key: &RequestLabels) -> bool {
        self.host == key.host && self.api == key.api
    }
}

fn test() {
    let family = Family::<RequestLabels, Counter>::default();

    fn call(host: &str, api: &str, family: &Family<RequestLabels, Counter>) {
        let labels = RequestLabelsQ {
            host, api,
        };

        let counter = family.get_or_create(&labels);
        counter.inc();
    }
}

This will require using hashbrown instead of std::collections::HashMap (but actually std map is wrapper on hashbrown).
Equivalent
HashMap::get
Also, it will affect the definition of Family::get_or_create but the behavior should be the same.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at Family::get_or_create and trace its std::collections::HashMap lookup. Read hashbrown::Equivalent and HashMap::get to understand the required lookup behavior, then inspect existing Family tests for the current API and semantics. Done means borrowed label data can look up an existing counter without cloning, while existing behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.