Bug 1379163: defer loading actions until needed; r=jonasfj
authorDustin J. Mitchell <dustin@mozilla.com>
Fri, 21 Jul 2017 14:36:31 +0000
changeset 419362 03896a3c7a68c0672e1fda121e357f9bc7511e62
parent 419361 aff22b63df7a936f2f3f94ac86ad78d43123f12f
child 419363 9efa1cfe64b1eeea5a202963bbe95ceceec0f53f
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonasfj
bugs1379163
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1379163: defer loading actions until needed; r=jonasfj This helps avoid import cycles MozReview-Commit-ID: E8T1sLvilht
taskcluster/actions/registry.py
--- a/taskcluster/actions/registry.py
+++ b/taskcluster/actions/registry.py
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import json
 import os
 import inspect
 import re
+from mozbuild.util import memoize
 from types import FunctionType
 from collections import namedtuple
 from taskgraph.util.docker import docker_image
 from taskgraph.parameters import Parameters
 from actions import util
 
 
 GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..'))
@@ -238,21 +239,21 @@ def register_callback_action(name, title
                         '--', 'bash', '-cx',
                         """\
 cd /home/worker/checkouts/gecko &&
 ln -s /home/worker/artifacts artifacts &&
 ./mach --log-no-times taskgraph action-callback""",
                     ],
                 },
                 'extra': {
-                      'treeherder': {
+                    'treeherder': {
                         'groupName': 'action-callback',
                         'groupSymbol': 'AC',
                         'symbol': symbol,
-                      },
+                    },
                 },
             }
         mem['registered'] = True
         callbacks[cb.__name__] = cb
     return register_callback
 
 
 def render_actions_json(parameters):
@@ -264,20 +265,19 @@ def render_actions_json(parameters):
     parameters : taskgraph.parameters.Parameters
         Decision task parameters.
 
     Returns
     -------
     dict
         JSON object representation of the ``public/actions.json`` artifact.
     """
-    global actions
     assert isinstance(parameters, Parameters), 'requires instance of Parameters'
     result = []
-    for action in sorted(actions, key=lambda action: action.order):
+    for action in sorted(get_actions(), key=lambda action: action.order):
         task = action.task_template_builder(parameters)
         if task:
             assert is_json(task), 'task must be a JSON compatible object'
             res = {
                 'kind': 'task',
                 'name': action.name,
                 'title': action.title,
                 'description': action.description,
@@ -298,23 +298,34 @@ def render_actions_json(parameters):
 
 
 def trigger_action_callback(task_group_id, task_id, task, input, callback, parameters,
                             test=False):
     """
     Trigger action callback with the given inputs. If `test` is true, then run
     the action callback in testing mode, without actually creating tasks.
     """
-    cb = callbacks.get(callback, None)
+    cb = get_callbacks().get(callback, None)
     if not cb:
         raise Exception('Unknown callback: {}'.format(callback))
 
     if test:
         util.testing = True
 
     cb(Parameters(**parameters), input, task_group_id, task_id, task)
 
 
-# Load all modules from this folder, relying on the side-effects of register_
-# functions to populate the action registry.
-for f in os.listdir(os.path.dirname(__file__)):
+@memoize
+def _load():
+    # Load all modules from this folder, relying on the side-effects of register_
+    # functions to populate the action registry.
+    for f in os.listdir(os.path.dirname(__file__)):
         if f.endswith('.py') and f not in ('__init__.py', 'registry.py'):
             __import__('actions.' + f[:-3])
+    return callbacks, actions
+
+
+def get_callbacks():
+    return _load()[0]
+
+
+def get_actions():
+    return _load()[1]