Skip to content

server: Add initial MetaStore#616

Merged
LucioFranco merged 1 commit intomainfrom
lucio/auth-namespace2
Dec 12, 2023
Merged

server: Add initial MetaStore#616
LucioFranco merged 1 commit intomainfrom
lucio/auth-namespace2

Conversation

@LucioFranco
Copy link
Contributor

@LucioFranco LucioFranco commented Nov 13, 2023

This PR adds a new internal metadata store for namespace configuration.
This internally uses a normal namespace so that the replica also get's
synchronized. This is just initial work there are a few more issues to
solve regarding replica's getting updated configs and some internal
hardening that needs to be done. Tracking issue for follow up work #768.

Closes #501

@psarna
Copy link
Contributor

psarna commented Nov 15, 2023

what's MetaStore?

@haaawk
Copy link
Collaborator

haaawk commented Nov 15, 2023

what's MetaStore?

Storage for metadata (aka namespace configs)

@LucioFranco LucioFranco force-pushed the lucio/auth-namespace2 branch 3 times, most recently from d86cc92 to 1e9ec0b Compare December 7, 2023 22:04
@LucioFranco LucioFranco marked this pull request as ready for review December 7, 2023 22:05
store: Namespace<T>,
}

async fn execute<B: QueryResultBuilder>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These next few functions I would like to refactor into a proper struct but for now this will do. Marked as follow up item 👍

let sender = lock.entry(namespace.clone()).or_insert_with(|| {
// TODO(lucio): if no entry exists we need to ensure we send the update to
// the bg channel.
let (tx, _) = watch::channel(Arc::new(DatabaseConfig::default()));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a follow up item for this in #768

@@ -0,0 +1 @@

Copy link
Contributor Author

@LucioFranco LucioFranco Dec 7, 2023

Choose a reason for hiding this comment

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

reserved for some tests that I will do as follow up but this will require getting bottomless backups also working in our test suite which may be a lot of work.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this will create more confusion than value. I don't think anyone will still the meta.rs file so I would just drop this from the PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a test here, these will be expanded upon in follow up PRs

@LucioFranco LucioFranco force-pushed the lucio/auth-namespace2 branch 4 times, most recently from 5ebc56a to c0d349d Compare December 8, 2023 02:01
@MarinPostma
Copy link
Contributor

As discussed in our call, I don't think this is the right approach. Instead, I propose that we do the following:

Configuration changes regarding a replica are propagated by mean of the replication protocol. The primary sends the relevant configuration to the replica in the handshake response. When the config for a replica changes, the primary requests a new handshake, and the replica updates its config.

@haaawk
Copy link
Collaborator

haaawk commented Dec 11, 2023

Member

@LucioFranco please make sure you split that work into two parts: on instance storage + primary/replica synchronization. The first part is blocking the per namespace jwts so it would be great to get it done quick.

@LucioFranco LucioFranco force-pushed the lucio/auth-namespace2 branch 3 times, most recently from c9ffaad to a545db6 Compare December 11, 2023 20:38
@LucioFranco LucioFranco force-pushed the lucio/auth-namespace2 branch from a545db6 to 6668911 Compare December 11, 2023 20:42
@LucioFranco
Copy link
Contributor Author

@haaawk ive extracted all the debug out into #777

@LucioFranco
Copy link
Contributor Author

@LucioFranco please make sure you split that work into two parts: on instance storage + primary/replica synchronization. The first part is blocking the per namespace jwts so it would be great to get it done quick.

Added a TODO to #768 @MarinPostma and I have a good idea how to do this and yes we can merge this now and unblock your work.

@LucioFranco LucioFranco force-pushed the lucio/auth-namespace2 branch from 6668911 to fdcb4a8 Compare December 11, 2023 21:41
@LucioFranco
Copy link
Contributor Author

@haaawk @MarinPostma this is ready for review and I've added a test as well.

@LucioFranco LucioFranco requested a review from haaawk December 11, 2023 21:43
@LucioFranco LucioFranco force-pushed the lucio/auth-namespace2 branch from fdcb4a8 to fce0516 Compare December 11, 2023 23:39

let rows = stmt.query(())?.mapped(|r| {
let ns = r.get::<_, String>(0)?;
let config = r.get::<_, Vec<u8>>(1)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

There's no need to allocate here, you can get a &[u8] and parse json straight from it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to change this to a borrowed version but since the row borrow is only for this closure we can't return it. I think since this is just a restore a string/vec is fine here, we can change if we find its really causing issues. Configs should be quite small anyways.

Comment on lines +31 to +32
Internal(Arc<Mutex<Arc<DatabaseConfig>>>),
External(mpsc::Sender<ChangeMsg>, Receiver<Arc<DatabaseConfig>>),
Copy link
Contributor

Choose a reason for hiding this comment

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

what's the purpose of those?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some unit tests use the internal so its a legacy thing that we can eventually remove but it was done in place to allow those tests to not have to update how they work with the metastore.

// when we are updating the config. The config si already synced via the watch
// channel.
configs: HashMap<NamespaceName, Sender<Arc<DatabaseConfig>>>,
db: Connection,
Copy link
Contributor

Choose a reason for hiding this comment

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

you should use a libsql_sys::Connection here instead

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I get it that you want to add durability in a subsequent PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added as follow up item in #768 (related to bottomless backup).

@MarinPostma
Copy link
Contributor

I left a few comments; feel free to dismiss, merge, and address them in a follow-up.


#[derive(Debug, Clone)]
enum HandleState {
Internal(Arc<Mutex<Arc<DatabaseConfig>>>),
Copy link
Collaborator

@haaawk haaawk Dec 12, 2023

Choose a reason for hiding this comment

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

Could we have Arc<Mutex<DatabaseConfig>>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Returned type expects an Arc<DatabaseConfig> so we unfortunately need to do this but that said this code should be test only and internal unit test so let me see if I can wrap in a cfg and we can forget about it until we refactor those tests.


let mut configs = HashMap::new();

for row in rows {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why two loops instead of looping over query results and do what this loop is doing straight away?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Conceptually and api wise, 1) being I like having the part that extracts out of the row be its own piece of code (but we rows doesn't implement iterator so we can't just loop) and 2) then putting the actual de serialization where we want some special logic in a separate block. Goal being that people should focus on the big for loop rather than the mapped rows section.

Copy link
Collaborator

@haaawk haaawk left a comment

Choose a reason for hiding this comment

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

LGTM

This PR adds a new internal metadata store for namespace configuration.
This internally uses a normal namespace so that the replica also get's
synchronized. This is just initial work there are a few more issues to
solve regarding replica's getting updated configs and some internal
hardening that needs to be done. Tracking issue for follow up work #768.

Closes #501
@LucioFranco LucioFranco added this pull request to the merge queue Dec 12, 2023
Merged via the queue into main with commit 5e28284 Dec 12, 2023
@LucioFranco LucioFranco deleted the lucio/auth-namespace2 branch December 12, 2023 18:48
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.

Backup namespace config

4 participants