Skip to content

Conversation

rainerschoe
Copy link
Member

closes #67

This implements waiting functions to allow the user to wait for the client to reach a certain state.

Thinking about #107 I think it is a good idea to distinguish waiting for a configuration to be available and waiting for getting online.

We can already serve features and properties even though we did not yet establish a connection with the server.

Comment on lines +97 to +100
let (current_mode_mutex, condition_variable) = &*self.current_mode;
let mut current_mode = current_mode_mutex.lock().unwrap();
*current_mode = CurrentMode::Defunct(result.clone());
condition_variable.notify_all();
Copy link
Member Author

@rainerschoe rainerschoe Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of a repeating pattern when working with condition variables.
WDYT should we add an abstraction to not always deal with the tuple and weird derefs? Something like:

use std::sync::{Mutex, Condvar};

struct Waitable<T> {
    value: Mutex<Option<T>>,
    condvar: Condvar,
}

impl<T> Waitable<T> {
    fn new() -> Self {
        Self {
            value: Mutex::new(None),
            condvar: Condvar::new(),
        }
    }

    fn set(&self, val: T) {
        let mut guard = self.value.lock().unwrap();
        *guard = Some(val);
        self.condvar.notify_all();
    }

    fn wait(&self) -> T {
        let mut guard = self.value.lock().unwrap();
        while guard.is_none() {
            guard = self.condvar.wait(guard).unwrap();
        }
        guard.take().unwrap()
    }
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, probably. There are some lines that are repeated again and again.

Signed-off-by: Travis <[email protected]>
@rainerschoe rainerschoe marked this pull request as draft September 8, 2025 08:58
Copy link
Collaborator

@jgsogo jgsogo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the implementation, but I really think it's time for a new trait related to online configurations.

Comment on lines 67 to +72
/// For remote configurations, it returns whether it's connected to the
/// remote or not
fn is_online(&self) -> Result<bool>;

/// For remote configurations: Blocks until it's connected to the remote.
fn wait_until_online(&self);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't want a different trait when we had only is_online, maybe now we can think about adding it

Comment on lines +74 to +77
/// Blocks until a configuration is available.
/// Note: This is different than wait_until_online, as configuration could be available
/// through alternate sources (Cache / Fallback)
fn wait_until_configuration_is_available(&self);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we need this as a first-class citizen here. Couldn't this information be retrieved via the initial config + is_online (+ maybe we need a way to get current status)?

Comment on lines +60 to +63
fn wait_until_online(&self) {
error!("Waiting for AppConfigurationOffline to get online. This will never happen.");
std::thread::park(); // block forever
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note my previous comment about using a different trait. This and Configuration shouldn't implement these methods.

Ok(self.get_current_mode()? == CurrentMode::Online)
}

fn wait_until_configuration_is_available(&self) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... I'm not really sure if we want to implement this behaviour. What is the use-case for this method?

Comment on lines +97 to +100
let (current_mode_mutex, condition_variable) = &*self.current_mode;
let mut current_mode = current_mode_mutex.lock().unwrap();
*current_mode = CurrentMode::Defunct(result.clone());
condition_variable.notify_all();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, probably. There are some lines that are repeated again and again.

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

Successfully merging this pull request may close these issues.

Wait for initial configuration to be ready
2 participants