You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by ke...@apache.org on 2025/12/11 15:51:25 UTC

(allura) branch master updated (099dfc335 -> e9b1b0dad)

This is an automated email from the ASF dual-hosted git repository.

kentontaylor pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


    from 099dfc335 upgrade urllib3 to latest
     new 12b6da77a [#8592] prepend __task_ for special delay and flush_immediately task/event params.  Add priority too
     new c2cb0b3fc [#8592] reindex tasks run at lower priority
     new e9b1b0dad [#8592] show less error details on failed macros for anonymous users (incl scripts like reindex)

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/command/show_models.py      |  4 +++-
 Allura/allura/lib/app_globals.py          | 20 +++++++++++++++++---
 Allura/allura/lib/decorators.py           | 24 +++++++++++++++++-------
 Allura/allura/lib/macro.py                | 15 +++++++++++++--
 Allura/allura/model/project.py            |  6 +++---
 Allura/allura/tests/test_commands.py      |  2 +-
 Allura/allura/tests/test_decorators.py    |  6 +++---
 Allura/allura/tests/test_tasks.py         |  4 ++--
 ForgeTracker/forgetracker/model/ticket.py |  2 +-
 9 files changed, 60 insertions(+), 23 deletions(-)


(allura) 03/03: [#8592] show less error details on failed macros for anonymous users (incl scripts like reindex)

Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kentontaylor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e9b1b0dad1a70ab246b0781826659e0ae34e3522
Author: Dave Brondsema <db...@slashdotmedia.com>
AuthorDate: Mon Dec 8 11:47:26 2025 -0500

    [#8592] show less error details on failed macros for anonymous users (incl scripts like reindex)
---
 Allura/allura/lib/macro.py | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index 61dbea85a..c3ebca198 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -104,8 +104,19 @@ def __call__(self, s):
             log.warning('macro error.  Upwards stack is %s',
                         ''.join(traceback.format_stack()),
                         exc_info=True)
-            msg = html.escape(f'[[{s}]] ({repr(ex)})')
-            return '\n<div class="error"><pre><code>%s</code></pre></div>' % msg
+            try:
+                current_user = g.user
+            except AttributeError:
+                anon_user = True  # test or background script
+            else:
+                anon_user = current_user.is_anonymous()
+            if anon_user:
+                # show a bit less detail
+                msg = html.escape(f'[[{s}]] (error processing macro)')
+                return f'\n<pre><code>{msg}</code></pre>'
+            else:
+                msg = html.escape(f'[[{s}]] ({ex})')
+                return f'\n<div class="error"><pre><code>{msg}</code></pre></div>'
 
     def _lookup_macro(self, s):
         macro = _macros.get(s)


(allura) 01/03: [#8592] prepend __task_ for special delay and flush_immediately task/event params. Add priority too

Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kentontaylor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 12b6da77a1465e4e79a4638aa0a3597d3b5d6f29
Author: Dave Brondsema <db...@slashdotmedia.com>
AuthorDate: Mon Dec 8 11:45:56 2025 -0500

    [#8592] prepend __task_ for special delay and flush_immediately task/event params.  Add priority too
---
 Allura/allura/lib/app_globals.py          | 20 +++++++++++++++++---
 Allura/allura/lib/decorators.py           | 24 +++++++++++++++++-------
 Allura/allura/model/project.py            |  6 +++---
 Allura/allura/tests/test_decorators.py    |  6 +++---
 Allura/allura/tests/test_tasks.py         |  4 ++--
 ForgeTracker/forgetracker/model/ticket.py |  2 +-
 6 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 33be87058..7f1e104f9 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -394,7 +394,21 @@ def get_timeline(self, *a, **kw):
             return NullActivityStreamDirector()
 
     def post_event(self, topic, *args, **kwargs):
-        if 'flush_immediately' not in kwargs:
+        """
+        Creates an 'event' task.  When it runs, it will call all matching @event_handler listeners.
+
+        :param topic: not used much, but passed through to listeners
+        :param args: not used much, but passed through to listeners
+        :param kwargs: not used much, but passed through to listeners
+        :param __task_delay: (optional) seconds to delay task execution (see MonQTask.post)
+        :param __task_priority: (optional) task priority (see MonQTask.post)
+        :return:
+        """
+        if 'flush_immediately' in kwargs and '__task_flush_immediately' not in kwargs:
+            # backwards compatibility
+            kwargs['__task_flush_immediately'] = kwargs.pop('flush_immediately')
+
+        if '__task_flush_immediately' not in kwargs:
             try:
                 env = request.environ
             except AttributeError:
@@ -402,12 +416,12 @@ def post_event(self, topic, *args, **kwargs):
             else:
                 script_without_ming_middleware = env['PATH_INFO'] == '--script--'
             if script_without_ming_middleware:
-                kwargs['flush_immediately'] = True
+                kwargs['__task_flush_immediately'] = True
             else:
                 # within tasks and web requests, ming middleware will flush everything to mongo
                 # so best to *not* flush immediately and let all db writes happen in order
                 # so there's no chance of an event being created and started while the initiating code is still running
-                kwargs['flush_immediately'] = False
+                kwargs['__task_flush_immediately'] = False
         allura.tasks.event_tasks.event.post(topic, *args, **kwargs)
 
     @LazyProperty
diff --git a/Allura/allura/lib/decorators.py b/Allura/allura/lib/decorators.py
index cd27647b4..f6c578168 100644
--- a/Allura/allura/lib/decorators.py
+++ b/Allura/allura/lib/decorators.py
@@ -41,17 +41,21 @@
 log = logging.getLogger(__name__)
 
 
-def task(*args, **kw):
+def task(*args, notifications_disabled=False):
     """Decorator that adds a ``.post()`` function to the decorated callable.
 
     Calling ``<original_callable>.post(*args, **kw)`` queues the callable for
     execution by a background worker process. All parameters must be
     BSON-serializable.
 
+    ``<original_callable>.post()`` takes optional keyword arguments `__task_delay`, `__task_priority`, and
+    `__task_flush_immediately` which will be passed to :meth:`allura.model.monq_model.MonQTask.post` to control the
+    task.
+
     Example usage::
 
         @task
-        def myfunc():
+        def myfunc(foo):
             pass
 
         @task(notifications_disabled=True)
@@ -59,17 +63,23 @@ def myotherfunc():
             # No email notifications will be sent for c.project during this task
             pass
 
+        myfunc.post(foo=bar, __task_delay=10)
+
     """
     def task_(func):
         def post(*args, **kwargs):
-            delay = kwargs.pop('delay', 0)
-            flush_immediately = kwargs.pop('flush_immediately', True)
+            # pass any __task_* kwargs to MonQTask.post instead of task function
+            task_kwargs = {}
+            for k, v in kwargs.copy().items():
+                if k.startswith('__task_'):
+                    task_kwargs[k[7:]] = kwargs.pop(k)
+                if k in ('delay', 'flush_immediately'):  # backwards compatibility for no __task_ prefix
+                    task_kwargs[k] = kwargs.pop(k)
             project = getattr(c, 'project', None)
-            cm = (h.notifications_disabled if project and
-                  kw.get('notifications_disabled') else h.null_contextmanager)
+            cm = h.notifications_disabled if project and notifications_disabled else h.null_contextmanager
             with cm(project):
                 from allura import model as M
-                return M.MonQTask.post(func, args, kwargs, delay=delay, flush_immediately=flush_immediately)
+                return M.MonQTask.post(func, args, kwargs, **task_kwargs)
         # if decorating a class, have to make it a staticmethod
         # or it gets a spurious cls argument
         func.post = staticmethod(post) if inspect.isclass(func) else post
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 23726135c..815ca9cad 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -122,13 +122,13 @@ def subcategories(self):
 class TroveCategoryMapperExtension(MapperExtension):
 
     def after_insert(self, obj, state, sess):
-        g.post_event('trove_category_created', obj.trove_cat_id, flush_immediately=True)
+        g.post_event('trove_category_created', obj.trove_cat_id, __task_flush_immediately=True)
 
     def after_update(self, obj, state, sess):
-        g.post_event('trove_category_updated', obj.trove_cat_id, flush_immediately=True)
+        g.post_event('trove_category_updated', obj.trove_cat_id, __task_flush_immediately=True)
 
     def after_delete(self, obj, state, sess):
-        g.post_event('trove_category_deleted', obj.trove_cat_id, flush_immediately=True)
+        g.post_event('trove_category_deleted', obj.trove_cat_id, __task_flush_immediately=True)
 
 
 class TroveCategory(MappedClass):
diff --git a/Allura/allura/tests/test_decorators.py b/Allura/allura/tests/test_decorators.py
index 638f365d7..5b7ed112f 100644
--- a/Allura/allura/tests/test_decorators.py
+++ b/Allura/allura/tests/test_decorators.py
@@ -35,7 +35,7 @@ def func():
         assert hasattr(func, 'post')
 
     def test_with_params(self):
-        @task(disable_notifications=True)
+        @task(notifications_disabled=True)
         def func():
             pass
         assert hasattr(func, 'post')
@@ -43,7 +43,7 @@ def func():
     @patch('allura.lib.decorators.c')
     @patch('allura.model.MonQTask')
     def test_post(self, c, MonQTask):
-        @task(disable_notifications=True)
+        @task(notifications_disabled=True)
         def func(s, foo=None, **kw):
             pass
 
@@ -57,7 +57,7 @@ def mock_post(f, args, kw, delay=None):
 
         c.project.notifications_disabled = False
         MonQTask.post.side_effect = mock_post
-        func.post('test', foo=2, delay=1)
+        func.post('test', foo=2, __task_delay=1)
 
 
 class TestMemoize:
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 95c24e9e3..5dfc88822 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -113,10 +113,10 @@ def test_fire_event(self):
         assert self.called_with == [((1, 2), {'a': 5})], self.called_with
 
     def test_post_event_explicit_flush(self):
-        g.post_event('my_event1', flush_immediately=True)
+        g.post_event('my_event1', __task_flush_immediately=True)
         assert M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event1'])
 
-        g.post_event('my_event2', flush_immediately=False)
+        g.post_event('my_event2', __task_flush_immediately=False)
         assert not M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event2'])
         ThreadLocalODMSession.flush_all()
         assert M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event2'])
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 8445e63c6..b0cba01f1 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -261,7 +261,7 @@ def invalidate_bin_counts(self):
             return
         self._bin_counts_invalidated = datetime.utcnow()
         from forgetracker import tasks  # prevent circular import
-        tasks.update_bin_counts.post(self.app_config_id, delay=delay)
+        tasks.update_bin_counts.post(self.app_config_id, __task_delay=delay)
 
     def sortable_custom_fields_shown_in_search(self):
         def solr_type(field_name):


(allura) 02/03: [#8592] reindex tasks run at lower priority

Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kentontaylor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c2cb0b3fc84d11163af466db9c8127def1d55020
Author: Dave Brondsema <db...@slashdotmedia.com>
AuthorDate: Mon Dec 8 11:46:16 2025 -0500

    [#8592] reindex tasks run at lower priority
---
 Allura/allura/command/show_models.py | 4 +++-
 Allura/allura/tests/test_commands.py | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/command/show_models.py b/Allura/allura/command/show_models.py
index 54555fc32..70695d98a 100644
--- a/Allura/allura/command/show_models.py
+++ b/Allura/allura/command/show_models.py
@@ -78,7 +78,8 @@ class ReindexCommand(base.Command):
                            'Note: this is often better, since tasks have "request" objects '
                            'which are needed for some markdown macros to run properly')
     parser.add_option('--solr-hosts', dest='solr_hosts',
-                      help='Override the solr host(s) to post to.  Comma-separated list of solr server URLs')
+                      help='Override the solr host(s) to post to.  Comma-separated list of solr server URLs. '
+                           'Passed through to tasks if --tasks is used.')
     parser.add_option('--solr-creds', dest='solr_creds',
                       help='Creds for the solr host(s).  Comma-separated list of user:pwd strings')
     parser.add_option(
@@ -181,6 +182,7 @@ def _post_add_artifacts(self, chunk):
                 add_artifacts.post(chunk,
                                    update_solr=self.options.solr,
                                    update_refs=self.options.refs,
+                                   __task_priority=5,  # lower than default 10
                                    **self.add_artifact_kwargs)
         except InvalidDocument as e:
             # there are many types of InvalidDocument, only recurse if its
diff --git a/Allura/allura/tests/test_commands.py b/Allura/allura/tests/test_commands.py
index 112557e42..104c5c997 100644
--- a/Allura/allura/tests/test_commands.py
+++ b/Allura/allura/tests/test_commands.py
@@ -555,7 +555,7 @@ def on_post(chunk, **kw):
         cmd = show_models.ReindexCommand('reindex')
         cmd.options, args = cmd.parser.parse_args([])
         cmd._post_add_artifacts(list(range(5)))
-        kw = {'update_solr': cmd.options.solr, 'update_refs': cmd.options.refs}
+        kw = {'update_solr': cmd.options.solr, 'update_refs': cmd.options.refs, '__task_priority': 5}
         expected = [
             call([0, 1, 2, 3, 4], **kw),
             call([0, 1], **kw),