Line data Source code
1 : //! Structs representing the JSON formats used in the compute_ctl's HTTP API.
2 :
3 : use std::fmt::Display;
4 :
5 : use chrono::{DateTime, Utc};
6 : use serde::{Deserialize, Serialize, Serializer};
7 :
8 : use crate::{
9 : privilege::Privilege,
10 : spec::{ComputeSpec, Database, ExtVersion, PgIdent, Role},
11 : };
12 :
13 0 : #[derive(Serialize, Debug, Deserialize)]
14 : pub struct GenericAPIError {
15 : pub error: String,
16 : }
17 :
18 : #[derive(Debug, Clone, Serialize)]
19 : pub struct ExtensionInstallResponse {
20 : pub extension: PgIdent,
21 : pub version: ExtVersion,
22 : }
23 :
24 : /// Response of the /status API
25 0 : #[derive(Serialize, Debug, Deserialize)]
26 : #[serde(rename_all = "snake_case")]
27 : pub struct ComputeStatusResponse {
28 : pub start_time: DateTime<Utc>,
29 : pub tenant: Option<String>,
30 : pub timeline: Option<String>,
31 : pub status: ComputeStatus,
32 : #[serde(serialize_with = "rfc3339_serialize")]
33 : pub last_active: Option<DateTime<Utc>>,
34 : pub error: Option<String>,
35 : }
36 :
37 0 : #[derive(Serialize, Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
38 : #[serde(rename_all = "snake_case")]
39 : pub enum ComputeStatus {
40 : // Spec wasn't provided at start, waiting for it to be
41 : // provided by control-plane.
42 : Empty,
43 : // Compute configuration was requested.
44 : ConfigurationPending,
45 : // Compute node has spec and initial startup and
46 : // configuration is in progress.
47 : Init,
48 : // Compute is configured and running.
49 : Running,
50 : // New spec is being applied.
51 : Configuration,
52 : // Either startup or configuration failed,
53 : // compute will exit soon or is waiting for
54 : // control-plane to terminate it.
55 : Failed,
56 : // Termination requested
57 : TerminationPending,
58 : // Terminated Postgres
59 : Terminated,
60 : }
61 :
62 : impl Display for ComputeStatus {
63 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 0 : match self {
65 0 : ComputeStatus::Empty => f.write_str("empty"),
66 0 : ComputeStatus::ConfigurationPending => f.write_str("configuration-pending"),
67 0 : ComputeStatus::Init => f.write_str("init"),
68 0 : ComputeStatus::Running => f.write_str("running"),
69 0 : ComputeStatus::Configuration => f.write_str("configuration"),
70 0 : ComputeStatus::Failed => f.write_str("failed"),
71 0 : ComputeStatus::TerminationPending => f.write_str("termination-pending"),
72 0 : ComputeStatus::Terminated => f.write_str("terminated"),
73 : }
74 0 : }
75 : }
76 :
77 0 : pub fn rfc3339_serialize<S>(x: &Option<DateTime<Utc>>, s: S) -> Result<S::Ok, S::Error>
78 0 : where
79 0 : S: Serializer,
80 0 : {
81 0 : if let Some(x) = x {
82 0 : x.to_rfc3339().serialize(s)
83 : } else {
84 0 : s.serialize_none()
85 : }
86 0 : }
87 :
88 : /// Response of the /metrics.json API
89 : #[derive(Clone, Debug, Default, Serialize)]
90 : pub struct ComputeMetrics {
91 : /// Time spent waiting in pool
92 : pub wait_for_spec_ms: u64,
93 :
94 : /// Time spent checking if safekeepers are synced
95 : pub sync_sk_check_ms: u64,
96 :
97 : /// Time spent syncing safekeepers (walproposer.c).
98 : /// In most cases this should be zero.
99 : pub sync_safekeepers_ms: u64,
100 :
101 : /// Time it took to establish a pg connection to the pageserver.
102 : /// This is two roundtrips, so it's a good proxy for compute-pageserver
103 : /// latency. The latency is usually 0.2ms, but it's not safe to assume
104 : /// that.
105 : pub pageserver_connect_micros: u64,
106 :
107 : /// Time to get basebackup from pageserver and write it to disk.
108 : pub basebackup_ms: u64,
109 :
110 : /// Compressed size of basebackup received.
111 : pub basebackup_bytes: u64,
112 :
113 : /// Time spent starting potgres. This includes initialization of shared
114 : /// buffers, preloading extensions, and other pg operations.
115 : pub start_postgres_ms: u64,
116 :
117 : /// Time spent applying pg catalog updates that were made in the console
118 : /// UI. This should be 0 when startup time matters, since cplane tries
119 : /// to do these updates eagerly, and passes the skip_pg_catalog_updates
120 : /// when it's safe to skip this step.
121 : pub config_ms: u64,
122 :
123 : /// Total time, from when we receive the spec to when we're ready to take
124 : /// pg connections.
125 : pub total_startup_ms: u64,
126 : pub load_ext_ms: u64,
127 : pub num_ext_downloaded: u64,
128 : pub largest_ext_size: u64, // these are measured in bytes
129 : pub total_ext_download_size: u64,
130 : }
131 :
132 : #[derive(Clone, Debug, Default, Serialize)]
133 : pub struct CatalogObjects {
134 : pub roles: Vec<Role>,
135 : pub databases: Vec<Database>,
136 : }
137 :
138 : /// Response of the `/computes/{compute_id}/spec` control-plane API.
139 : /// This is not actually a compute API response, so consider moving
140 : /// to a different place.
141 0 : #[derive(Deserialize, Debug)]
142 : pub struct ControlPlaneSpecResponse {
143 : pub spec: Option<ComputeSpec>,
144 : pub status: ControlPlaneComputeStatus,
145 : }
146 :
147 0 : #[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
148 : #[serde(rename_all = "snake_case")]
149 : pub enum ControlPlaneComputeStatus {
150 : // Compute is known to control-plane, but it's not
151 : // yet attached to any timeline / endpoint.
152 : Empty,
153 : // Compute is attached to some timeline / endpoint and
154 : // should be able to start with provided spec.
155 : Attached,
156 : }
157 :
158 : #[derive(Clone, Debug, Default, Serialize)]
159 : pub struct InstalledExtension {
160 : pub extname: String,
161 : pub version: String,
162 : pub n_databases: u32, // Number of databases using this extension
163 : pub owned_by_superuser: String,
164 : }
165 :
166 : #[derive(Clone, Debug, Default, Serialize)]
167 : pub struct InstalledExtensions {
168 : pub extensions: Vec<InstalledExtension>,
169 : }
170 :
171 : #[derive(Clone, Debug, Default, Serialize)]
172 : pub struct ExtensionInstallResult {
173 : pub extension: PgIdent,
174 : pub version: ExtVersion,
175 : }
176 : #[derive(Clone, Debug, Default, Serialize)]
177 : pub struct SetRoleGrantsResponse {
178 : pub database: PgIdent,
179 : pub schema: PgIdent,
180 : pub privileges: Vec<Privilege>,
181 : pub role: PgIdent,
182 : }
|