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

pageserver: generation number fetch on startup and use in /attach #5163

Merged
merged 46 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
e839fd1
libs: add Generation::previous
jcsp Aug 31, 2023
1cedf33
pageserver_api: add types for control plane calls
jcsp Aug 25, 2023
bf4572f
pageserver: optional generation input during create & attach
jcsp Aug 24, 2023
233afac
pageserver: add control_plane_api conf
jcsp Aug 25, 2023
ac8ef22
pageserver: call into control plane on startup
jcsp Aug 25, 2023
44e6125
pageserver: if control plane API is disabled, ignore generations
jcsp Aug 29, 2023
38d5dec
pageserver: generation-aware index_part.json loading
jcsp Aug 29, 2023
885537a
control_plane: add `attachement_service`, a mock control plane
jcsp Aug 25, 2023
08fac67
neon_local: manage attachment_service
jcsp Aug 25, 2023
5e49aa5
control_plane: implement attach hook
jcsp Aug 29, 2023
2ebe12e
remote_storage: fix LocalFs list_files
jcsp Aug 29, 2023
9deaa1b
tests: enable generations in neon_fixture
jcsp Aug 29, 2023
af28cd1
clippy: permit many args to schedule_local_tenant_processing
jcsp Aug 31, 2023
acce508
Refactor TenantId encoding in JSON APIs
jcsp Aug 31, 2023
1856d75
clippy
jcsp Aug 31, 2023
e2bf591
Update pageserver/src/tenant/remote_timeline_client/download.rs
jcsp Sep 1, 2023
fd2ea25
Update pageserver/src/tenant/remote_timeline_client.rs
jcsp Sep 1, 2023
5fc0874
Update pageserver/src/tenant/remote_timeline_client.rs
jcsp Sep 1, 2023
891f7c4
More consistent handling of generations in pageserver API
jcsp Sep 1, 2023
8ea760a
clippy
jcsp Sep 1, 2023
4d6b89d
refactor control plane client
jcsp Sep 1, 2023
9a5899c
Cancellation and exponential backoff in control plane re-attach
jcsp Sep 1, 2023
2649114
Fix Generation::previous and refactor suffix parsing
jcsp Sep 1, 2023
a983485
More efficient .max()
jcsp Sep 1, 2023
c1ca773
Tighten up download_index_part
jcsp Sep 1, 2023
9dc2f72
remove unused constructor arg
jcsp Sep 1, 2023
bb278aa
Apply suggestions from code review
jcsp Sep 1, 2023
fb36329
Handle control plane URLs without a trailing slash
jcsp Sep 1, 2023
2553e48
Fix python lint complaint
jcsp Sep 1, 2023
1cea6fb
Merge remote-tracking branch 'upstream/main' into jcsp/generation-num…
jcsp Sep 4, 2023
2af98aa
fixup merge
jcsp Sep 4, 2023
a88fa7d
Use safe tenant dir deletion in /re-attach handling
jcsp Sep 4, 2023
85c737e
Update pageserver/src/tenant/remote_timeline_client/download.rs
jcsp Sep 6, 2023
03c5ab0
Apply suggestions from code review
jcsp Sep 6, 2023
382a930
Cleanup of attachment_service binary
jcsp Sep 6, 2023
008545c
improve logging in index part download
jcsp Sep 6, 2023
864fb74
libs: flatten a match{}
jcsp Sep 6, 2023
32548c7
flatten a match{}
jcsp Sep 6, 2023
bc32ec6
Use DisplayFromStr instead of hex
jcsp Sep 6, 2023
6467853
Add track_caller to functions that can panic
jcsp Sep 6, 2023
386542e
clippy
jcsp Sep 6, 2023
8837479
Add a log span to a unit test
jcsp Sep 6, 2023
966b5e3
Merge remote-tracking branch 'upstream/main' into jcsp/generation-num…
jcsp Sep 6, 2023
606a392
pageserver: fix layer reconciliation with generations
jcsp Sep 5, 2023
db3dc06
Apply suggestions from code review
jcsp Sep 6, 2023
562e47e
unwrap_or_else
jcsp Sep 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions control_plane/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ git-version.workspace = true
nix.workspace = true
once_cell.workspace = true
postgres.workspace = true
hex.workspace = true
hyper.workspace = true
regex.workspace = true
reqwest = { workspace = true, features = ["blocking", "json"] }
serde.workspace = true
Expand All @@ -20,6 +22,7 @@ serde_with.workspace = true
tar.workspace = true
thiserror.workspace = true
toml.workspace = true
tokio.workspace = true
url.workspace = true
# Note: Do not directly depend on pageserver or safekeeper; use pageserver_api or safekeeper_api
# instead, so that recompile times are better.
Expand Down
104 changes: 104 additions & 0 deletions control_plane/src/attachment_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use crate::{background_process, local_env::LocalEnv};
use anyhow::anyhow;
use serde::{Deserialize, Serialize};
use std::{path::PathBuf, process::Child};
use utils::id::{NodeId, TenantId};

pub struct AttachmentService {
env: LocalEnv,
listen: String,
path: PathBuf,
}

const COMMAND: &str = "attachment_service";

#[derive(Serialize, Deserialize)]
pub struct AttachHookRequest {
#[serde(with = "hex")]
pub tenant_id: TenantId,
pub pageserver_id: Option<NodeId>,
}

#[derive(Serialize, Deserialize)]
pub struct AttachHookResponse {
pub gen: Option<u32>,
}

impl AttachmentService {
pub fn from_env(env: &LocalEnv) -> Self {
let path = env.base_data_dir.join("attachments.json");

// Makes no sense to construct this if pageservers aren't going to use it: assume
// pageservers have control plane API set
let listen_url = env.pageserver.control_plane_api.clone().unwrap();

let listen = format!(
"{}:{}",
listen_url.host_str().unwrap(),
listen_url.port().unwrap()
);

Self {
env: env.clone(),
path,
listen,
}
}

fn pid_file(&self) -> PathBuf {
self.env.base_data_dir.join("attachment_service.pid")
}

pub fn start(&self) -> anyhow::Result<Child> {
let path_str = self.path.to_string_lossy();

background_process::start_process(
COMMAND,
&self.env.base_data_dir,
&self.env.attachment_service_bin(),
["-l", &self.listen, "-p", &path_str],
[],
background_process::InitialPidFile::Create(&self.pid_file()),
// TODO: a real status check
|| Ok(true),
)
}

pub fn stop(&self, immediate: bool) -> anyhow::Result<()> {
background_process::stop_process(immediate, COMMAND, &self.pid_file())
}

/// Call into the attach_hook API, for use before handing out attachments to pageservers
pub fn attach_hook(
&self,
tenant_id: TenantId,
pageserver_id: NodeId,
) -> anyhow::Result<Option<u32>> {
use hyper::StatusCode;

let url = self
.env
.pageserver
.control_plane_api
.clone()
.unwrap()
.join("attach_hook")
.unwrap();
let client = reqwest::blocking::ClientBuilder::new()
.build()
.expect("Failed to construct http client");

let request = AttachHookRequest {
tenant_id,
pageserver_id: Some(pageserver_id),
};

let response = client.post(url).json(&request).send()?;
if response.status() != StatusCode::OK {
return Err(anyhow!("Unexpected status {0}", response.status()));
jcsp marked this conversation as resolved.
Show resolved Hide resolved
}

let response = response.json::<AttachHookResponse>()?;
Ok(response.gen)
}
}
Loading