Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide API to go from Guard<Option<Arc<T>>> to Option<Guard<Arc<T>>> #90

Open
stepancheg opened this issue Apr 5, 2023 · 2 comments
Open

Comments

@stepancheg
Copy link

stepancheg commented Apr 5, 2023

The use case is this: configuration is stored in global variable as:

static CFG: ArcSwap<Option<Arc<String>>> = ...

now I want to write a function which returns a configuration, but initializes if it is not initialized yet:

fn get_cfg() -> Guard<Arc<String>> {
  let cfg = CFG.load();
  if cfg.is_some() {
    return ???
  }

  ... initialize
}

I'm thinking there should be an operation like:

impl<T> Guard<Option<Arc<T>>> {
  pub fn transpose(self) -> Option<Guard<Arc<T>>> { ... }
}

Similarly, ArcSwap<Option<Arc<T>>> could have a shortcut:

impl<T> ArcSwap<Option<Arc<T>>> {
  fn load(&self) -> Option<Guard<Arc<T>>> { ... }
}

I don't know if Guard can do it transparently, alternatively, arc_swap can provide something like SomeGuard<T>.

@stepancheg stepancheg changed the title Provide API to go from Guard<Option<Arc<T>> to Option<Guard<Arc<T>>> Provide API to go from Guard<Option<Arc<T>>> to Option<Guard<Arc<T>>> Apr 5, 2023
@vorner
Copy link
Owner

vorner commented Apr 7, 2023

First, I assume you mean ArcSwapOption<String> (which is internally `ArcSwapAny<Option<Arc>>), what you have up there would have too many Arc-layers involved.

Also, I'm not sure if what you describe would rather be done by something like:

Lazy<ArcSwap<String>> = Lazy::new(|| {
    todo!()
});

Given these options, I'm not sure if such transpose would be that useful. On the other hand, I think it should be possible to implement because AFAIK the internal representation of Guard<Arc<T>> and Guard<Option<Arc<T>>> are the same.

If you still think there's a use case for such method, I'd be open for a pull request, but:

  • It should be more generic than just Guard<Option<Arc<T>>> ‒ all the other things run on R: RefCnt, S: Strategy.
  • Shouldn't be a method but rather an inherent function (one shall need to call Guard::transpose(g), not g.transpose, because Guard is a "smart pointer" and shouldn't shadow methods on whatever it points to).
  • I don't like the load shortcut, for two reasons ‒ load already exists for that type and returns something else and as mentioned, need for such operation is likely rare, so I wouldn't like to pollute the "base type" (there's already a lot of methods on it).

If you need some specific pointers on how to get oriented in the code, you can ask, but I don't really have that much spare time lately and won't be able to write the code myself.

@stepancheg
Copy link
Author

would rather be done by something like
Lazy

That was too simplified example, sorry. Proper example should be returning Result.

static CFG: ArcSwap<Option<Arc<MyCfg>>> = ...

fn get_cfg() -> anyhow::Result<Guard<Arc<MyCfg>>> {
  let cfg = CFG.load();
  if cfg.is_some() {
    return ???
  }

  ... initialize, return error if failed to initialize configuration
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants