Skip to content

Commit 2154008

Browse files
committed
Patched in Add an argument to ipcluster plugin to specify the number of engines (jtriley#547)
1 parent a2e7e2f commit 2154008

1 file changed

Lines changed: 35 additions & 16 deletions

File tree

starcluster/plugins/ipcluster.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def _start_engines(node, user, n_engines=None, kill_existing=False):
7171
n_engines = node.num_processors
7272
node.ssh.switch_user(user)
7373
if kill_existing:
74-
node.ssh.execute("pkill -f ipengineapp", ignore_exit_status=True)
74+
node.ssh.execute("pkill -f IPython.parallel.engine", ignore_exit_status=True)
7575
node.ssh.execute("ipcluster engines --n=%i --daemonize" % n_engines)
7676
node.ssh.switch_user('root')
7777

@@ -91,7 +91,7 @@ class IPCluster(DefaultClusterSetup):
9191
9292
"""
9393
def __init__(self, enable_notebook=False, notebook_passwd=None,
94-
notebook_directory=None, packer=None, log_level='INFO'):
94+
notebook_directory=None, packer=None, master_engines=None, node_engines=None, log_level='INFO'):
9595
super(IPCluster, self).__init__()
9696
if isinstance(enable_notebook, basestring):
9797
self.enable_notebook = enable_notebook.lower().strip() == 'true'
@@ -100,6 +100,8 @@ def __init__(self, enable_notebook=False, notebook_passwd=None,
100100
self.notebook_passwd = notebook_passwd or utils.generate_passwd(16)
101101
self.notebook_directory = notebook_directory
102102
self.log_level = log_level
103+
self.master_engines = master_engines
104+
self.node_engines = node_engines
103105
if packer not in (None, 'json', 'pickle', 'msgpack'):
104106
log.error("Unsupported packer: %s", packer)
105107
self.packer = None
@@ -163,7 +165,11 @@ def _write_config(self, master, user, profile_dir):
163165
f.close()
164166

165167
def _start_cluster(self, master, profile_dir):
166-
n_engines = max(1, master.num_processors - 1)
168+
if self.master_engines is None:
169+
n_engines = max(1, master.num_processors - 1)
170+
else:
171+
n_engines = int(self.master_engines)
172+
print "Setting master engines to '%s'" % self.master_engines
167173
log.info("Starting the IPython controller and %i engines on master"
168174
% n_engines)
169175
# cleanup existing connection files, to prevent their use
@@ -215,7 +221,7 @@ def _start_cluster(self, master, profile_dir):
215221
self._authorize_port(master, (1000, 65535), "IPython controller")
216222
return local_json, n_engines
217223

218-
def _start_notebook(self, master, user, profile_dir):
224+
def _start_notebook(self, master, user, profile_dir, time_to_dead=60.0):
219225
log.info("Setting up IPython web notebook for user: %s" % user)
220226
user_cert = posixpath.join(profile_dir, '%s.pem' % user)
221227
ssl_cert = posixpath.join(profile_dir, '%s.pem' % user)
@@ -242,6 +248,7 @@ def _start_notebook(self, master, user, profile_dir):
242248
"c.NotebookApp.open_browser = False",
243249
"c.NotebookApp.password = u'%s'" % sha1pass,
244250
"c.NotebookApp.port = %d" % notebook_port,
251+
"c.NotebookApp.time_to_dead = %d" % time_to_dead,
245252
]))
246253
f.close()
247254
if self.notebook_directory is not None:
@@ -288,12 +295,16 @@ def run(self, nodes, master, user, user_shell, volumes):
288295
cfile, n_engines_master = self._start_cluster(master, profile_dir)
289296
# Start engines on each of the non-master nodes
290297
non_master_nodes = [node for node in nodes if not node.is_master()]
298+
n_engines_non_master = 0
291299
for node in non_master_nodes:
300+
if self.node_engines is None:
301+
n_engines = node.num_processors
302+
else:
303+
n_engines = int(self.node_engines)
292304
self.pool.simple_job(
293-
_start_engines, (node, user, node.num_processors),
305+
_start_engines, (node, user, n_engines),
294306
jobid=node.alias)
295-
n_engines_non_master = sum(node.num_processors
296-
for node in non_master_nodes)
307+
n_engines_non_master += n_engines
297308
if len(non_master_nodes) > 0:
298309
log.info("Adding %d engines on %d nodes",
299310
n_engines_non_master, len(non_master_nodes))
@@ -310,9 +321,12 @@ def run(self, nodes, master, user, user_shell, volumes):
310321

311322
def on_add_node(self, node, nodes, master, user, user_shell, volumes):
312323
self._check_ipython_installed(node)
313-
n_engines = node.num_processors
324+
if self.node_engines is None:
325+
n_engines = node.num_processors
326+
else:
327+
n_engines = int(self.node_engines)
314328
log.info("Adding %d engines on %s", n_engines, node.alias)
315-
_start_engines(node, user)
329+
_start_engines(node, user, n_engines)
316330

317331
def on_remove_node(self, node, nodes, master, user, user_shell, volumes):
318332
raise NotImplementedError("on_remove_node method not implemented")
@@ -332,7 +346,7 @@ def run(self, nodes, master, user, user_shell, volumes):
332346
master.ssh.execute("ipcluster stop", ignore_exit_status=True)
333347
time.sleep(2)
334348
log.info("Stopping IPython controller on %s", master.alias)
335-
master.ssh.execute("pkill -f ipcontrollerapp",
349+
master.ssh.execute("pkill -f IPython.parallel.controller",
336350
ignore_exit_status=True)
337351
master.ssh.execute("pkill -f 'ipython notebook'",
338352
ignore_exit_status=True)
@@ -344,7 +358,7 @@ def run(self, nodes, master, user, user_shell, volumes):
344358

345359
def _stop_engines(self, node, user):
346360
node.ssh.switch_user(user)
347-
node.ssh.execute("pkill -f ipengineapp", ignore_exit_status=True)
361+
node.ssh.execute("pkill -f IPython.parallel.engine", ignore_exit_status=True)
348362
node.ssh.switch_user('root')
349363

350364
def on_add_node(self, node, nodes, master, user, user_shell, volumes):
@@ -354,7 +368,7 @@ def on_remove_node(self, node, nodes, master, user, user_shell, volumes):
354368
raise NotImplementedError("on_remove_node method not implemented")
355369

356370

357-
class IPClusterRestartEngines(DefaultClusterSetup):
371+
class IPClusterRestartEngines(IPCluster):
358372
"""Plugin to kill and restart all engines of an IPython cluster
359373
360374
This plugin can be useful to hard-reset the all the engines, for instance
@@ -364,14 +378,19 @@ class IPClusterRestartEngines(DefaultClusterSetup):
364378
This plugin is meant to be run manually with:
365379
366380
starcluster runplugin plugin_conf_name cluster_name
367-
368381
"""
369382
def run(self, nodes, master, user, user_shell, volumes):
370383
n_total = 0
371384
for node in nodes:
372-
n_engines = node.num_processors
373-
if node.is_master() and n_engines > 2:
374-
n_engines -= 1
385+
if node.is_master() and (self.master_engines is not None):
386+
n_engines = int(self.master_engines)
387+
elif self.node_engines is not None:
388+
n_engines = int(self.node_engines)
389+
elif node.is_master():
390+
# and n_engines > 2: # XXX I'm not sure I understand this logic yet.
391+
n_engines = node.num_processors - 1
392+
else:
393+
n_engines = node.num_processors
375394
self.pool.simple_job(
376395
_start_engines, (node, user, n_engines, True),
377396
jobid=node.alias)

0 commit comments

Comments
 (0)