vorner/arc-swap

How to use the map API against more than one sub-fields of the bigger struct

lnshi opened this issue ยท 3 comments

lnshi commented

First, thanks for this amazing crate.

I checked that the map API tells:

Motivation

Sometimes, an application consists of components. Each component has its own configuration structure. The whole configuration contains all the smaller config parts.

For the sake of separation and abstraction, it is not desirable to pass the whole configuration to each of the components. This allows the component to take only access to its own part.

But i a bit stuck to figure out what is the proper way to use the map API against more than one sub-fields of the bigger struct, say i have the below structures:

struct Config {
  // a, b are coupled: if a get updated, b must get updated also
  a: HashMap<String, String>,
  b: HashMap<String, String>,
  // others
}

let cfg = Config{..};
let aswap_cfg = arc_swap:ArcSwap::from(Arc::new(cfg))

// This is problematic as between two loads some threads might have changed the data.
let a_cfg = aswap_cfg.map(|cfg: &Config| cfg.a).load();
let b_cfg = aswap_cfg.map(|cfg: &Config| cfg.b).load();

// Currently i have to load the whole Config struct
let cfg = aswap_cfg.load();
// Then use cfg.a or cfg.b

Is there a better way i can utilise the map API to address this concern or i have to group a and b under one more level?

Hello

I don't know of a direct support for this in arcswap. What comes to mind is:

  • Create some kind of wrapper yourself โ€’ wrap the Guard<โ€ฆ> returned from load and have methods to accessing a() and b() on that. This is more or less what Map does, but has only one projection, you could have a trait with multiple.
  • Bundle a and be into a sub-struct:
  a: ...
  b: ...
}

struct Config {
  a_and_b: AAndB
}

I know these are not perfect, but the Map API is already somewhat problematic ๐Ÿ˜‡

If you have better ideas of how to do such support in here, I'm all ears ๐Ÿ˜‡.

lnshi commented

thanks for the prompt reply, for now i think i will go with the approach that grouping a and b under another field.

Ok, then I'm going to close this.