@@ -27,8 +27,9 @@ use serde::Deserialize;
2727use serde_json:: json;
2828use tokio:: sync:: RwLock ;
2929use tracing:: * ;
30+ use url:: Url ;
3031
31- use crate :: controllers:: { Diagnostics , State } ;
32+ use crate :: controllers:: { service_url , Diagnostics , State } ;
3233use crate :: metrics:: Metrics ;
3334use crate :: resources:: restateclusters:: RestateCluster ;
3435use crate :: resources:: restatedeployments:: {
@@ -151,7 +152,7 @@ impl RestateDeployment {
151152 let rs_api = Api :: < ReplicaSet > :: namespaced ( ctx. client . clone ( ) , namespace) ;
152153 let svc_api = Api :: < Service > :: namespaced ( ctx. client . clone ( ) , namespace) ;
153154
154- let admin_endpoint = self . spec . restate . register . url ( ) ?;
155+ let admin_endpoint = self . spec . restate . register . admin_url ( ) ?;
155156
156157 let pod_template_annotation = reconcilers:: replicaset:: pod_template_annotation ( self ) ;
157158
@@ -277,15 +278,28 @@ impl RestateDeployment {
277278 )
278279 . await ?;
279280
280- let service_endpoint =
281- format ! ( "http://{versioned_name}.{namespace}.svc.cluster.local:9080/" ) ;
281+ let service_endpoint = service_url (
282+ & versioned_name,
283+ namespace,
284+ 9080 ,
285+ self . spec . restate . service_path . as_deref ( ) ,
286+ ) ?;
282287
283- let mut endpoints = self
284- . list_endpoints ( & ctx. http_client , & admin_endpoint)
288+ let mut deployments = self
289+ . list_deployments ( & ctx. http_client , & admin_endpoint)
285290 . await ?;
286291
287- // if the endpoint is not active, register it
288- if !endpoints. get ( & service_endpoint) . cloned ( ) . unwrap_or ( false ) {
292+ let existing_deployment_id = replicaset
293+ . annotations ( )
294+ . get ( RESTATE_DEPLOYMENT_ID_ANNOTATION ) ;
295+
296+ // if the repliceset doesn't have a deployment id, or its deployment id is not active, register it
297+ if existing_deployment_id. is_none_or ( |existing_deployment_id| {
298+ !deployments
299+ . get ( existing_deployment_id)
300+ . cloned ( )
301+ . unwrap_or_default ( )
302+ } ) {
289303 if let Some ( cluster_name) = & self . spec . restate . register . cluster {
290304 // wait for the cluster to be ready before registering to it
291305 validate_cluster_status ( rsc_api, cluster_name) . await ?;
@@ -302,7 +316,8 @@ impl RestateDeployment {
302316 )
303317 . await ?;
304318 // if registration succeeded, treat this as an active endpoint
305- endpoints. insert ( service_endpoint. clone ( ) , true ) ;
319+ // if we fail after this point we will re-register and should get the same deployment id
320+ deployments. insert ( deployment_id. clone ( ) , true ) ;
306321
307322 debug ! ( "Updating deployment-id annotation of ReplicaSet/Service {versioned_name} in namespace {namespace}" ) ;
308323
@@ -338,7 +353,7 @@ impl RestateDeployment {
338353 & ctx. http_client ,
339354 & admin_endpoint,
340355 self ,
341- & endpoints ,
356+ & deployments ,
342357 )
343358 . await ?;
344359
@@ -475,8 +490,8 @@ impl RestateDeployment {
475490 /// Register a service version with the Restate cluster
476491 async fn register_service_with_restate (
477492 client : & reqwest:: Client ,
478- admin_endpoint : & str ,
479- service_endpoint : & str ,
493+ admin_endpoint : & Url ,
494+ service_endpoint : & Url ,
480495 ) -> Result < String > {
481496 debug ! ( "Registering endpoint '{service_endpoint}' to Restate at '{admin_endpoint}'" , ) ;
482497
@@ -486,7 +501,7 @@ impl RestateDeployment {
486501 }
487502
488503 let resp: DeploymentResponse = client
489- . post ( format ! ( "{} /deployments", admin_endpoint ) )
504+ . post ( admin_endpoint . join ( " /deployments") ? )
490505 . json ( & serde_json:: json!( {
491506 "uri" : service_endpoint,
492507 } ) )
@@ -502,14 +517,14 @@ impl RestateDeployment {
502517 Ok ( resp. id )
503518 }
504519
505- async fn list_endpoints (
520+ pub async fn list_deployments (
506521 & self ,
507522 http_client : & reqwest:: Client ,
508- admin_endpoint : & str ,
523+ admin_endpoint : & Url ,
509524 ) -> Result < HashMap < String , bool > > {
510- // This query finds endpoint urls, noting those that are the latest for a particular service, or have an active invocation
525+ // This query finds deployments, noting those that are the latest for a particular service, or have an active invocation
511526 let sql_query = r#"
512- SELECT d.endpoint , (s.name IS NOT NULL OR i.id IS NOT NULL) as active
527+ SELECT d.id as deployment_id , (s.name IS NOT NULL OR i.id IS NOT NULL) as active
513528 FROM sys_deployment d
514529 LEFT JOIN sys_service s ON (d.id = s.deployment_id)
515530 LEFT JOIN sys_invocation_status i ON (d.id = i.pinned_deployment_id);
@@ -522,12 +537,12 @@ impl RestateDeployment {
522537
523538 #[ derive( Deserialize ) ]
524539 struct DeploymentQueryResultRow {
525- endpoint : String ,
540+ deployment_id : String ,
526541 active : bool ,
527542 }
528543
529544 let response: DeploymentQueryResult = http_client
530- . post ( format ! ( "{} /query", admin_endpoint ) )
545+ . post ( admin_endpoint . join ( " /query") ? )
531546 . header ( reqwest:: header:: ACCEPT , "application/json" )
532547 . json ( & serde_json:: json!( {
533548 "query" : sql_query
@@ -544,10 +559,10 @@ impl RestateDeployment {
544559 let mut endpoints = HashMap :: with_capacity ( response. rows . len ( ) ) ;
545560
546561 for row in response. rows {
547- match endpoints. entry ( row. endpoint ) {
562+ match endpoints. entry ( row. deployment_id ) {
548563 std:: collections:: hash_map:: Entry :: Occupied ( mut entry) => {
549- // technically there can be multiple deployments with the same endpoint url (via different headers, etc)
550- // we treat the endpoint as active if any such deployment is active
564+ // two rows with same deployment id shouldnt happen...
565+ // we treat the deployment as active if any row is active
551566 if !entry. get ( ) {
552567 entry. insert ( row. active ) ;
553568 }
@@ -595,10 +610,10 @@ impl RestateDeployment {
595610 } ;
596611 }
597612
598- let admin_endpoint = self . spec . restate . register . url ( ) ?;
613+ let admin_endpoint = self . spec . restate . register . admin_url ( ) ?;
599614
600- let endpoints = self
601- . list_endpoints ( & ctx. http_client , & admin_endpoint)
615+ let deployments = self
616+ . list_deployments ( & ctx. http_client , & admin_endpoint)
602617 . await ?;
603618
604619 let ( active_count, next_removal) = reconcilers:: replicaset:: cleanup_old_replicasets (
@@ -608,7 +623,7 @@ impl RestateDeployment {
608623 & ctx. http_client ,
609624 & admin_endpoint,
610625 self ,
611- & endpoints ,
626+ & deployments ,
612627 )
613628 . await ?;
614629
0 commit comments