1- use anyhow:: Result ;
1+ use anyhow:: * ;
22use gas:: prelude:: * ;
33use rivet_api_builder:: ApiCtx ;
44use serde:: { Deserialize , Serialize } ;
@@ -91,6 +91,12 @@ pub struct ReplicaReconfigureRequest {}
9191#[ serde( deny_unknown_fields) ]
9292pub struct ReplicaReconfigureResponse { }
9393
94+ /// Triggers the epoxy coordinator to reconfigure all replicas.
95+ ///
96+ /// Useful when a replica's configuration is outdated for any reason and needs to be re-notified of
97+ /// changes.
98+ ///
99+ /// This should never need to be called manually if everything is operating correctly.
94100pub async fn epoxy_replica_reconfigure (
95101 ctx : ApiCtx ,
96102 _path : ( ) ,
@@ -107,3 +113,74 @@ pub async fn epoxy_replica_reconfigure(
107113
108114 Ok ( ReplicaReconfigureResponse { } )
109115}
116+
117+ #[ derive( Serialize ) ]
118+ #[ serde( deny_unknown_fields) ]
119+ pub struct GetEpoxyStateResponse {
120+ pub config : epoxy:: types:: ClusterConfig ,
121+ }
122+
123+ /// Returns the current epoxy coordinator cluster configuration.
124+ ///
125+ /// Useful for inspecting the current state of the epoxy cluster, including all replicas and their statuses.
126+ pub async fn get_epoxy_state ( ctx : ApiCtx , _path : ( ) , _query : ( ) ) -> Result < GetEpoxyStateResponse > {
127+ let workflow_id = ctx
128+ . find_workflow :: < epoxy:: workflows:: coordinator:: Workflow > ( (
129+ "replica" ,
130+ ctx. config ( ) . epoxy_replica_id ( ) ,
131+ ) )
132+ . await ?
133+ . ok_or_else ( || anyhow ! ( "epoxy coordinator workflow not found" ) ) ?;
134+
135+ let wfs = ctx. get_workflows ( vec ! [ workflow_id] ) . await ?;
136+ let wf = wfs. first ( ) . ok_or_else ( || anyhow ! ( "workflow not found" ) ) ?;
137+
138+ let state: epoxy:: workflows:: coordinator:: State =
139+ wf. parse_state ( ) . context ( "failed to parse workflow state" ) ?;
140+
141+ Ok ( GetEpoxyStateResponse {
142+ config : state. config ,
143+ } )
144+ }
145+
146+ #[ derive( Deserialize ) ]
147+ #[ serde( deny_unknown_fields) ]
148+ pub struct SetEpoxyStateRequest {
149+ pub config : epoxy:: types:: ClusterConfig ,
150+ }
151+
152+ #[ derive( Serialize ) ]
153+ #[ serde( deny_unknown_fields) ]
154+ pub struct SetEpoxyStateResponse { }
155+
156+ /// Overrides the epoxy coordinator cluster configuration and triggers reconfiguration.
157+ ///
158+ /// Useful for manually adjusting the cluster state in case the replica status drifts from the
159+ /// state in the coordinator. This will automatically trigger a reconfigure when called.
160+ ///
161+ /// This should never need to be called manually if everything is operating correctly.
162+ pub async fn set_epoxy_state (
163+ ctx : ApiCtx ,
164+ _path : ( ) ,
165+ _query : ( ) ,
166+ body : SetEpoxyStateRequest ,
167+ ) -> Result < SetEpoxyStateResponse > {
168+ ensure ! (
169+ body. config. coordinator_replica_id == ctx. config( ) . epoxy_replica_id( ) ,
170+ "config coordinator_replica_id ({}) does not match current replica id ({})" ,
171+ body. config. coordinator_replica_id,
172+ ctx. config( ) . epoxy_replica_id( )
173+ ) ;
174+
175+ if ctx. config ( ) . is_leader ( ) {
176+ ctx. signal ( epoxy:: workflows:: coordinator:: OverrideState {
177+ config : body. config ,
178+ } )
179+ . to_workflow :: < epoxy:: workflows:: coordinator:: Workflow > ( )
180+ . tag ( "replica" , ctx. config ( ) . epoxy_replica_id ( ) )
181+ . send ( )
182+ . await ?;
183+ }
184+
185+ Ok ( SetEpoxyStateResponse { } )
186+ }
0 commit comments