Files
neon/pageserver
Christian Schwarz 7e80d7b864 DatadirModification::flush: pre-lock layer map
This is preliminary work for/from #4220 (async `Layer::get_value_reconstruct_data`).

There, we want to switch `Timeline::layers` to be a `tokio::sync::RwLock`.

The problem with `DatadirModification::flush` is that it uses `TimelineWriter::put`,
and that method needs to lock `Timeline::layers` down the call tree.

So, `TimelineWriter::put` will needs to become async.

But `DatadirModification::flush` calls `put()` from inside the `retain`
closure. That won't work once `put()` becomes async, because there are no async closures in Rust.

I'm not aware of an `async`-compatible alternative for `retain`.

Hence, this patch pre-locks `Timeline::layers`, then passes the guard to the closure.

Deadlocks
=========

`TimelineWriter::put` needs to lock `Timeline::layers` when it needs to create a new `open` layer.

While we hold the `Timeline::layers` locked, the flush loop timeline task
can't make progress.

But the flush loop isn't running yet in these cases.

So, I'm wondering, what actually happens at runtime if the bootstrap / basebackup import fills
up the first `open` layer. What turns it `frozen`? Is anything flushing?
2023-06-12 16:58:18 +02:00
..