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