@@ -491,6 +491,15 @@ async def _scale(self, n, worker_group="default"):
491
491
custom_objects_api .api_client .set_default_header (
492
492
"content-type" , "application/merge-patch+json"
493
493
)
494
+ # Disable adaptivity if enabled
495
+ with suppress (kubernetes .client .ApiException ):
496
+ await custom_objects_api .delete_namespaced_custom_object (
497
+ group = "kubernetes.dask.org" ,
498
+ version = "v1" ,
499
+ plural = "daskautoscalers" ,
500
+ namespace = self .namespace ,
501
+ name = self .name ,
502
+ )
494
503
await custom_objects_api .patch_namespaced_custom_object_scale (
495
504
group = "kubernetes.dask.org" ,
496
505
version = "v1" ,
@@ -500,11 +509,59 @@ async def _scale(self, n, worker_group="default"):
500
509
body = {"spec" : {"replicas" : n }},
501
510
)
502
511
503
- def adapt (self , * args , ** kwargs ):
504
- """Turn on adaptivity"""
505
- raise NotImplementedError (
506
- "Adaptive mode is not supported yet for this KubeCluster."
507
- )
512
+ def adapt (self , minimum = None , maximum = None ):
513
+ """Turn on adaptivity
514
+
515
+ Parameters
516
+ ----------
517
+ minimum : int
518
+ Minimum number of workers
519
+ minimum : int
520
+ Maximum number of workers
521
+
522
+ Examples
523
+ --------
524
+ >>> cluster.adapt() # Allow scheduler to add/remove workers within k8s cluster resource limits
525
+ >>> cluster.adapt(minimum=1, maximum=10) # Allow scheduler to add/remove workers within 1-10 range
526
+ """
527
+ return self .sync (self ._adapt , minimum , maximum )
528
+
529
+ async def _adapt (self , minimum = None , maximum = None ):
530
+ async with kubernetes .client .api_client .ApiClient () as api_client :
531
+ custom_objects_api = kubernetes .client .CustomObjectsApi (api_client )
532
+ custom_objects_api .api_client .set_default_header (
533
+ "content-type" , "application/merge-patch+json"
534
+ )
535
+ try :
536
+ await custom_objects_api .patch_namespaced_custom_object_scale (
537
+ group = "kubernetes.dask.org" ,
538
+ version = "v1" ,
539
+ plural = "daskautoscalers" ,
540
+ namespace = self .namespace ,
541
+ name = self .name ,
542
+ body = {"spec" : {"minimum" : minimum , "maximum" : maximum }},
543
+ )
544
+ except kubernetes .client .ApiException :
545
+ await custom_objects_api .create_namespaced_custom_object (
546
+ group = "kubernetes.dask.org" ,
547
+ version = "v1" ,
548
+ plural = "daskautoscalers" ,
549
+ namespace = self .namespace ,
550
+ body = {
551
+ "apiVersion" : "kubernetes.dask.org/v1" ,
552
+ "kind" : "DaskAutoscaler" ,
553
+ "metadata" : {
554
+ "name" : self .name ,
555
+ "dask.org/cluster-name" : self .cluster_name ,
556
+ "dask.org/component" : "autoscaler" ,
557
+ },
558
+ "spec" : {
559
+ "cluster" : self .cluster_name ,
560
+ "minimum" : minimum ,
561
+ "maximum" : maximum ,
562
+ },
563
+ },
564
+ )
508
565
509
566
def _build_scheduler_spec (self , cluster_name ):
510
567
# TODO: Take the values provided in the current class constructor
0 commit comments