Skip to content

Commit 95789d5

Browse files
committed
fix setting config on common base classes
replace Mixin with Launcher, since it's a public config API and it's not really a Mixin, it must be Configurable for its traits to be configurable...
1 parent 68e4397 commit 95789d5

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

ipyparallel/cluster/launcher.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,7 @@
2929

3030
from subprocess import Popen, PIPE, STDOUT
3131

32-
try:
33-
from subprocess import check_output
34-
except ImportError:
35-
# pre-2.7, define check_output with Popen
36-
def check_output(*args, **kwargs):
37-
kwargs.update(dict(stdout=PIPE))
38-
p = Popen(*args, **kwargs)
39-
out, err = p.communicate()
40-
return out
32+
from subprocess import check_output
4133

4234

4335
from traitlets import import_item
@@ -51,7 +43,6 @@ def check_output(*args, **kwargs):
5143
Unicode,
5244
Dict,
5345
Instance,
54-
HasTraits,
5546
CRegExp,
5647
observe,
5748
)
@@ -220,7 +211,7 @@ def signal(self, sig):
220211
raise NotImplementedError('signal must be implemented in a subclass')
221212

222213

223-
class ClusterAppMixin(HasTraits):
214+
class ClusterAppMixin(LoggingConfigurable):
224215
"""MixIn for cluster args as traits"""
225216

226217
profile_dir = Unicode('')
@@ -231,7 +222,7 @@ def cluster_args(self):
231222
return ['--profile-dir', self.profile_dir, '--cluster-id', self.cluster_id]
232223

233224

234-
class ControllerMixin(ClusterAppMixin):
225+
class ControllerLauncher(ClusterAppMixin):
235226
controller_cmd = List(
236227
ipcontroller_cmd_argv,
237228
config=True,
@@ -245,7 +236,7 @@ class ControllerMixin(ClusterAppMixin):
245236
)
246237

247238

248-
class EngineMixin(ClusterAppMixin):
239+
class EngineLauncher(ClusterAppMixin):
249240
engine_cmd = List(
250241
ipengine_cmd_argv, config=True, help="""command to launch the Engine."""
251242
)
@@ -370,7 +361,7 @@ def poll(self):
370361
return status
371362

372363

373-
class LocalControllerLauncher(LocalProcessLauncher, ControllerMixin):
364+
class LocalControllerLauncher(LocalProcessLauncher, ControllerLauncher):
374365
"""Launch a controller as a regular external process."""
375366

376367
def find_args(self):
@@ -381,7 +372,7 @@ def start(self):
381372
return super(LocalControllerLauncher, self).start()
382373

383374

384-
class LocalEngineLauncher(LocalProcessLauncher, EngineMixin):
375+
class LocalEngineLauncher(LocalProcessLauncher, EngineLauncher):
385376
"""Launch a single engine as a regular external process."""
386377

387378
def find_args(self):
@@ -521,7 +512,7 @@ def start(self, n):
521512
return super(MPILauncher, self).start()
522513

523514

524-
class MPIControllerLauncher(MPILauncher, ControllerMixin):
515+
class MPIControllerLauncher(MPILauncher, ControllerLauncher):
525516
"""Launch a controller using mpiexec."""
526517

527518
# alias back to *non-configurable* program[_args] for use in find_args()
@@ -540,7 +531,7 @@ def start(self):
540531
return super(MPIControllerLauncher, self).start(1)
541532

542533

543-
class MPIEngineSetLauncher(MPILauncher, EngineMixin):
534+
class MPIEngineSetLauncher(MPILauncher, EngineLauncher):
544535
"""Launch engines using mpiexec"""
545536

546537
# alias back to *non-configurable* program[_args] for use in find_args()
@@ -762,7 +753,7 @@ def cluster_args(self):
762753
return ['--profile-dir', self.remote_profile_dir]
763754

764755

765-
class SSHControllerLauncher(SSHClusterLauncher, ControllerMixin):
756+
class SSHControllerLauncher(SSHClusterLauncher, ControllerLauncher):
766757

767758
# alias back to *non-configurable* program[_args] for use in find_args()
768759
# this way all Controller/EngineSetLaunchers have the same form, rather
@@ -789,7 +780,7 @@ def _to_fetch_default(self):
789780
]
790781

791782

792-
class SSHEngineLauncher(SSHClusterLauncher, EngineMixin):
783+
class SSHEngineLauncher(SSHClusterLauncher, EngineLauncher):
793784

794785
# alias back to *non-configurable* program[_args] for use in find_args()
795786
# this way all Controller/EngineSetLaunchers have the same form, rather

ipyparallel/tests/test_cluster.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ def ClusterConstructor(**kwargs):
3939
pytest.skip("requires mpiexec")
4040

4141
cfg = kwargs.setdefault("config", Config())
42-
cfg.EngineMixin.engine_args = ['--log-level=10']
43-
cfg.ControllerMixin.controller_args = ['--log-level=10']
42+
cfg.EngineLauncher.engine_args = ['--log-level=10']
43+
cfg.ControllerLauncher.controller_args = ['--log-level=10']
4444
kwargs.setdefault("controller_args", ['--ping=250'])
4545

4646
c = cluster.Cluster(**kwargs)
47+
assert c.config is cfg
4748
request.addfinalizer(c.stop_cluster_sync)
4849
return c
4950

@@ -72,6 +73,8 @@ async def test_start_stop_controller(Cluster):
7273
await cluster.start_controller()
7374
with pytest.raises(RuntimeError):
7475
await cluster.start_controller()
76+
assert cluster.config is not None
77+
assert cluster._controller.config is cluster.config
7578
assert cluster._controller is not None
7679
proc = cluster._controller.process
7780
assert proc.poll() is None
@@ -91,11 +94,17 @@ async def test_start_stop_controller(Cluster):
9194
async def test_start_stop_engines(Cluster, engine_launcher_class):
9295
cluster = Cluster(engine_launcher_class=engine_launcher_class)
9396
await cluster.start_controller()
94-
engine_set_id = await cluster.start_engines(n=3)
97+
98+
n = 3
99+
engine_set_id = await cluster.start_engines(n)
95100
assert engine_set_id in cluster._engine_sets
96101
engine_set = cluster._engine_sets[engine_set_id]
97102
launcher_class = find_launcher_class(engine_launcher_class, "EngineSet")
98103
assert isinstance(engine_set, launcher_class)
104+
105+
with cluster.connect_client() as rc:
106+
rc.wait_for_engines(n, timeout=_timeout)
107+
99108
await cluster.stop_engines(engine_set_id)
100109
assert cluster._engine_sets == {}
101110
with pytest.raises(KeyError):

0 commit comments

Comments
 (0)