Bug 1379163: defer loading actions until needed; r?jonasfj draft
authorDustin J. Mitchell <dustin@mozilla.com>
Fri, 21 Jul 2017 14:36:31 +0000
changeset 614541 c16dddc55e148fa1a4cb85b9da4cd5a1a86ce288
parent 614540 fd9294650ca557f1a59af4361d15b01310f939e7
child 638888 f8fca7f609fd74fc793eb4f7dcfbe10d5236ca15
push id70037
push userdmitchell@mozilla.com
push dateMon, 24 Jul 2017 17:55:55 +0000
reviewersjonasfj
bugs1379163
milestone56.0a1
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]