@@ -109,7 +109,7 @@ class ServiceProfile:
109
109
This includes how the service should be run, and conditions related to the scaling of the service.
110
110
"""
111
111
112
- def __init__ (self , name : str , container_config : DockerConfig , config_hash : int = 0 , min_instances :int = 0 , max_instances :int = None ,
112
+ def __init__ (self , name : str , container_config : DockerConfig , config_blob : str = '' , min_instances :int = 0 , max_instances :int = None ,
113
113
growth : float = 600 , shrink : Optional [float ] = None , backlog :int = 500 , queue = None , shutdown_seconds :int = 30 ):
114
114
"""
115
115
:param name: Name of the service to manage
@@ -127,7 +127,7 @@ def __init__(self, name: str, container_config: DockerConfig, config_hash:int=0,
127
127
self .high_duty_cycle = 0.7
128
128
self .low_duty_cycle = 0.5
129
129
self .shutdown_seconds = shutdown_seconds
130
- self .config_hash = config_hash
130
+ self .config_blob = config_blob
131
131
132
132
# How many instances we want, and can have
133
133
self .min_instances : int = max (0 , int (min_instances ))
@@ -211,7 +211,7 @@ def __deepcopy__(self, memodict=None):
211
211
prof = ServiceProfile (
212
212
name = self .name ,
213
213
container_config = DockerConfig (self .container_config .as_primitives ()),
214
- config_hash = self .config_hash ,
214
+ config_blob = self .config_blob ,
215
215
min_instances = self .min_instances ,
216
216
max_instances = self .max_instances ,
217
217
growth = self .growth_threshold ,
@@ -378,7 +378,7 @@ def prepare_container(docker_config: DockerConfig) -> DockerConfig:
378
378
# noinspection PyBroadException
379
379
try :
380
380
if service .enabled and (stage == ServiceStage .Off or name not in self .profiles ):
381
- # Enable this service's dependencies
381
+ # Enable this service's dependencies before trying to launch the service containers
382
382
self .controller .prepare_network (service .name , service .docker_config .allow_internet_access )
383
383
for _n , dependency in service .dependencies .items ():
384
384
dependency .container = prepare_container (dependency .container )
@@ -401,14 +401,22 @@ def prepare_container(docker_config: DockerConfig) -> DockerConfig:
401
401
402
402
# Check that all enabled services are enabled
403
403
if service .enabled and stage == ServiceStage .Running :
404
- # Compute a hash of service properties not include in the docker config, that
404
+ # Compute a blob of service properties not include in the docker config, that
405
405
# should still result in a service being restarted when changed
406
- config_hash = hash ( str (sorted (service .config .items () )))
407
- config_hash = hash (( config_hash , str (service .submission_params )) )
406
+ config_blob = str (sorted (service .config .items ()))
407
+ config_blob += str (service .submission_params )
408
408
409
409
# Build the docker config for the service, we are going to either create it or
410
410
# update it so we need to know what the current configuration is either way
411
411
docker_config = prepare_container (service .docker_config )
412
+ config_blob += str (docker_config )
413
+
414
+ # Build the docker config for the dependencies.
415
+ dependency_config = {}
416
+ for _n , dependency in service .dependencies .items ():
417
+ dependency .container = prepare_container (dependency .container )
418
+ dependency_config [_n ] = dependency
419
+ config_blob += str (sorted (dependency_config .items ()))
412
420
413
421
# Add the service to the list of services being scaled
414
422
with self .profiles_lock :
@@ -419,7 +427,7 @@ def prepare_container(docker_config: DockerConfig) -> DockerConfig:
419
427
min_instances = default_settings .min_instances ,
420
428
growth = default_settings .growth ,
421
429
shrink = default_settings .shrink ,
422
- config_hash = config_hash ,
430
+ config_blob = config_blob ,
423
431
backlog = default_settings .backlog ,
424
432
max_instances = service .licence_count ,
425
433
container_config = docker_config ,
@@ -436,13 +444,25 @@ def prepare_container(docker_config: DockerConfig) -> DockerConfig:
436
444
else :
437
445
profile ._max_instances = service .licence_count
438
446
439
- if profile .container_config != docker_config or profile . config_hash != config_hash :
447
+ if profile .config_blob != config_blob :
440
448
self .log .info (f"Updating deployment information for { name } " )
449
+ # Update the dependencies. Should do nothing if container spec is the same.
450
+ # let kubernetes decide if anything needs to change though.
451
+ for _n , dependency in dependency_config .items ():
452
+ self .controller .start_stateful_container (
453
+ service_name = service .name ,
454
+ container_name = _n ,
455
+ spec = dependency ,
456
+ labels = {'dependency_for' : service .name }
457
+ )
458
+
459
+ # Update the service itself
441
460
profile .container_config = docker_config
442
- profile .config_hash = config_hash
461
+ profile .config_blob = config_blob
443
462
self .controller .restart (profile )
444
463
self .log .info (f"Deployment information for { name } replaced" )
445
464
465
+
446
466
except Exception :
447
467
self .log .exception (f"Error applying service settings from: { service .name } " )
448
468
self .handle_service_error (service .name )
0 commit comments