@@ -11,7 +11,10 @@ use chrono::TimeDelta;
11
11
use chrono:: Utc ;
12
12
use clap:: Args ;
13
13
use clap:: Subcommand ;
14
+ use nexus_client:: types:: PendingRecovery ;
14
15
use nexus_client:: types:: QuiesceState ;
16
+ use nexus_client:: types:: QuiesceStatus ;
17
+ use nexus_client:: types:: SagaQuiesceStatus ;
15
18
use std:: time:: Duration ;
16
19
17
20
#[ derive( Debug , Args ) ]
@@ -31,9 +34,9 @@ pub enum QuiesceCommands {
31
34
32
35
#[ derive( Debug , Args ) ]
33
36
pub struct QuiesceShowArgs {
34
- /// Show details about held database connections
37
+ /// Show stack traces for held database connections
35
38
#[ clap( short, long, default_value_t = false ) ]
36
- verbose : bool ,
39
+ stacks : bool ,
37
40
}
38
41
39
42
pub async fn cmd_nexus_quiesce (
@@ -60,7 +63,10 @@ async fn quiesce_show(
60
63
. await
61
64
. context ( "fetching quiesce state" ) ?
62
65
. into_inner ( ) ;
63
- match quiesce. state {
66
+
67
+ let QuiesceStatus { db_claims, sagas, state } = quiesce;
68
+
69
+ match state {
64
70
QuiesceState :: Undetermined => {
65
71
println ! ( "has not yet determined if it is quiescing" ) ;
66
72
}
@@ -145,25 +151,83 @@ async fn quiesce_show(
145
151
}
146
152
}
147
153
148
- println ! ( "sagas running: {}" , quiesce. sagas_pending. len( ) ) ;
149
- for saga in & quiesce. sagas_pending {
154
+ let SagaQuiesceStatus {
155
+ sagas_pending,
156
+ drained_blueprint_id,
157
+ first_recovery_complete,
158
+ new_sagas_allowed,
159
+ reassignment_blueprint_id,
160
+ reassignment_generation,
161
+ reassignment_pending,
162
+ recovered_blueprint_id,
163
+ recovered_reassignment_generation,
164
+ recovery_pending,
165
+ } = sagas;
166
+
167
+ println ! ( "saga quiesce:" ) ;
168
+ println ! ( " new sagas: {:?}" , new_sagas_allowed) ;
169
+ println ! (
170
+ " drained as of blueprint: {}" ,
171
+ drained_blueprint_id
172
+ . map( |s| s. to_string( ) )
173
+ . as_deref( )
174
+ . unwrap_or( "none" )
175
+ ) ;
176
+ println ! (
177
+ " blueprint for last completed recovery pass: {}" ,
178
+ recovered_blueprint_id
179
+ . map( |s| s. to_string( ) )
180
+ . as_deref( )
181
+ . unwrap_or( "none" )
182
+ ) ;
183
+ println ! (
184
+ " blueprint for last reassignment pass: {}" ,
185
+ reassignment_blueprint_id
186
+ . map( |s| s. to_string( ) )
187
+ . as_deref( )
188
+ . unwrap_or( "none" )
189
+ ) ;
190
+ println ! (
191
+ " reassignment generation: {} (pass running: {})" ,
192
+ reassignment_generation,
193
+ if reassignment_pending { "yes" } else { "no" }
194
+ ) ;
195
+ println ! ( " recovered generation: {}" , recovered_reassignment_generation) ;
196
+ println ! (
197
+ " recovered at least once successfully: {}" ,
198
+ if first_recovery_complete { "yes" } else { "no" } ,
199
+ ) ;
200
+ print ! ( " recovery pending: " ) ;
201
+ if let Some ( PendingRecovery { generation, blueprint_id } ) = recovery_pending
202
+ {
203
+ println ! (
204
+ "yes (generation {}, blueprint id {})" ,
205
+ generation,
206
+ blueprint_id. map( |s| s. to_string( ) ) . as_deref( ) . unwrap_or( "none" )
207
+ ) ;
208
+ } else {
209
+ println ! ( "no" ) ;
210
+ }
211
+
212
+ println ! ( " sagas running: {}" , sagas_pending. len( ) ) ;
213
+ for saga in & sagas_pending {
150
214
println ! (
151
- " saga {} pending since {} ({})" ,
215
+ " saga {} pending since {} ({})" ,
152
216
saga. saga_id,
153
217
humantime:: format_rfc3339_millis( saga. time_pending. into( ) ) ,
154
218
saga. saga_name
155
219
) ;
156
220
}
157
221
158
- println ! ( "database connections held: {}" , quiesce . db_claims. len( ) ) ;
159
- for claim in & quiesce . db_claims {
222
+ println ! ( "database connections held: {}" , db_claims. len( ) ) ;
223
+ for claim in & db_claims {
160
224
println ! (
161
225
" claim {} held since {} ({} ago)" ,
162
226
claim. id,
163
227
claim. held_since,
164
228
format_time_delta( Utc :: now( ) - claim. held_since) ,
165
229
) ;
166
- if args. verbose {
230
+ if args. stacks {
167
231
println ! ( " acquired by:" ) ;
168
232
println ! ( "{}" , textwrap:: indent( & claim. debug, " " ) ) ;
169
233
}
@@ -177,7 +241,7 @@ async fn quiesce_start(
177
241
_token : DestructiveOperationToken ,
178
242
) -> Result < ( ) , anyhow:: Error > {
179
243
client. quiesce_start ( ) . await . context ( "quiescing Nexus" ) ?;
180
- quiesce_show ( client, & QuiesceShowArgs { verbose : false } ) . await
244
+ quiesce_show ( client, & QuiesceShowArgs { stacks : false } ) . await
181
245
}
182
246
183
247
fn format_duration_ms ( duration : Duration ) -> String {
0 commit comments