@@ -901,12 +901,20 @@ def _has_environment_changed() -> bool:
901901 return completion_status
902902
903903 @python_api_analytics
904- def run_janitor (self , ignore_ttl : bool , force_delete : bool = False ) -> bool :
904+ def run_janitor (
905+ self ,
906+ ignore_ttl : bool ,
907+ force_delete : bool = False ,
908+ environment : t .Optional [str ] = None ,
909+ ) -> bool :
910+ if environment is not None :
911+ environment = Environment .sanitize_name (environment )
912+
905913 success = False
906914
907915 if self .console .start_cleanup (ignore_ttl ):
908916 try :
909- self ._run_janitor (ignore_ttl , force_delete = force_delete )
917+ self ._run_janitor (ignore_ttl , force_delete = force_delete , environment = environment )
910918 success = True
911919 finally :
912920 self .console .stop_cleanup (success = success )
@@ -1926,7 +1934,7 @@ def invalidate_environment(self, name: str, sync: bool = False) -> None:
19261934 name = Environment .sanitize_name (name )
19271935 self .state_sync .invalidate_environment (name )
19281936 if sync :
1929- self ._cleanup_environments ()
1937+ self ._cleanup_environments (name = name )
19301938 self .console .log_success (f"Environment '{ name } ' deleted." )
19311939 else :
19321940 self .console .log_success (f"Environment '{ name } ' invalidated." )
@@ -3026,27 +3034,35 @@ def _destroy(self) -> bool:
30263034
30273035 return True
30283036
3029- def _run_janitor (self , ignore_ttl : bool = False , force_delete : bool = False ) -> None :
3037+ def _run_janitor (
3038+ self ,
3039+ ignore_ttl : bool = False ,
3040+ force_delete : bool = False ,
3041+ environment : t .Optional [str ] = None ,
3042+ ) -> None :
30303043 current_ts = now_timestamp ()
30313044 failures : t .List [str ] = []
30323045
30333046 # Clean up expired environments by removing their views and schemas
30343047 failures .extend (
3035- self ._cleanup_environments (current_ts = current_ts , force_delete = force_delete )
3048+ self ._cleanup_environments (
3049+ current_ts = current_ts , force_delete = force_delete , name = environment
3050+ )
30363051 )
30373052
3038- failures .extend (
3039- delete_expired_snapshots (
3040- self .state_sync ,
3041- self .snapshot_evaluator ,
3042- current_ts = current_ts ,
3043- ignore_ttl = ignore_ttl ,
3044- force_delete = force_delete ,
3045- console = self .console ,
3046- batch_size = self .config .janitor .expired_snapshots_batch_size ,
3053+ if environment is None :
3054+ failures .extend (
3055+ delete_expired_snapshots (
3056+ self .state_sync ,
3057+ self .snapshot_evaluator ,
3058+ current_ts = current_ts ,
3059+ ignore_ttl = ignore_ttl ,
3060+ force_delete = force_delete ,
3061+ console = self .console ,
3062+ batch_size = self .config .janitor .expired_snapshots_batch_size ,
3063+ )
30473064 )
3048- )
3049- self .state_sync .compact_intervals ()
3065+ self .state_sync .compact_intervals ()
30503066
30513067 if failures :
30523068 failure_string = "\n - " .join (failures )
@@ -3059,15 +3075,23 @@ def _run_janitor(self, ignore_ttl: bool = False, force_delete: bool = False) ->
30593075 raise SQLMeshError (summary )
30603076
30613077 def _cleanup_environments (
3062- self , current_ts : t .Optional [int ] = None , force_delete : bool = False
3078+ self ,
3079+ current_ts : t .Optional [int ] = None ,
3080+ force_delete : bool = False ,
3081+ name : t .Optional [str ] = None ,
30633082 ) -> t .List [str ]:
30643083 current_ts = current_ts or now_timestamp ()
30653084 failures : t .List [str ] = []
30663085
30673086 expired_environments_summaries = self .state_sync .get_expired_environments (
3068- current_ts = current_ts
3087+ current_ts = current_ts , name = name
30693088 )
30703089
3090+ if name is not None and not expired_environments_summaries :
3091+ self .console .log_warning (
3092+ f"Environment '{ name } ' is not expired or does not exist. Nothing to clean up."
3093+ )
3094+
30713095 for expired_env_summary in expired_environments_summaries :
30723096 expired_env = self .state_reader .get_environment (expired_env_summary .name )
30733097
@@ -3084,7 +3108,7 @@ def _cleanup_environments(
30843108 # we want to retry on the next janitor pass if drops failed, unless
30853109 # force_delete is set in which case we purge state records regardless
30863110 if not failures or force_delete :
3087- self .state_sync .delete_expired_environments (current_ts = current_ts )
3111+ self .state_sync .delete_expired_environments (current_ts = current_ts , name = name )
30883112 return failures
30893113
30903114 def _try_connection (self , connection_name : str , validator : t .Callable [[], None ]) -> None :
0 commit comments