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

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


The following commit(s) were added to refs/heads/master by this push:
     new 07b084ccb fix solr 413 request too big for big batches
07b084ccb is described below

commit 07b084ccbdaa29b4ec774ec68d0bcf1d164e769a
Author: Dillon Walls <[email protected]>
AuthorDate: Thu Nov 2 17:50:51 2023 +0000

    fix solr 413 request too big for big batches
---
 Allura/allura/lib/solr.py             | 10 +++++++++-
 Allura/allura/tasks/index_tasks.py    | 21 ++++++++++++++++++++-
 Allura/allura/tests/unit/test_solr.py | 12 ++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/lib/solr.py b/Allura/allura/lib/solr.py
index 79c7f61c5..49c76afb3 100644
--- a/Allura/allura/lib/solr.py
+++ b/Allura/allura/lib/solr.py
@@ -20,8 +20,10 @@ import json
 import logging
 
 from tg import config
+from webob.exc import HTTPRequestEntityTooLarge
 from paste.deploy.converters import asbool
 import pysolr
+from pysolr import SolrError
 import six
 
 from allura.lib.helpers import shlex_split
@@ -102,7 +104,13 @@ class Solr:
             kw['commitWithin'] = self.commitWithin
         responses = []
         for solr in self.push_pool:
-            responses.append(solr.add(*args, **kw))
+            try:
+                responses.append(solr.add(*args, **kw))
+            except SolrError as e:
+                if '(HTTP 413)' in str(e):
+                    raise HTTPRequestEntityTooLarge() from e
+                else:
+                    raise
         return responses
 
     def delete(self, *args, **kw):
diff --git a/Allura/allura/tasks/index_tasks.py 
b/Allura/allura/tasks/index_tasks.py
index 0ce2f7b28..b38aec1a7 100644
--- a/Allura/allura/tasks/index_tasks.py
+++ b/Allura/allura/tasks/index_tasks.py
@@ -14,13 +14,16 @@
 #       KIND, either express or implied.  See the License for the
 #       specific language governing permissions and limitations
 #       under the License.
+from __future__ import annotations
 
 import sys
 import logging
 from contextlib import contextmanager
+import typing
 
 from tg import app_globals as g
 from tg import tmpl_context as c
+from webob.exc import HTTPRequestEntityTooLarge
 
 from allura.lib import helpers as h
 from allura.lib.decorators import task
@@ -28,6 +31,9 @@ from allura.lib.exceptions import CompoundError
 from allura.lib.solr import make_solr_from_config
 import six
 
+if typing.TYPE_CHECKING:
+    import pysolr
+
 
 log = logging.getLogger(__name__)
 
@@ -126,7 +132,20 @@ def add_artifacts(ref_ids, update_solr=True, 
update_refs=True, solr_hosts=None):
             except Exception:
                 log.error('Error indexing artifact %s', ref._id)
                 exceptions.append(sys.exc_info())
-        __get_solr(solr_hosts).add(solr_updates)
+
+        def _add_artifact(solr: pysolr.Solr, artifacts: list):
+            try:
+                solr.add(artifacts)
+            except HTTPRequestEntityTooLarge:
+                if len(artifacts) > 1:
+                    log.warning(f"Solr.add raised HTTPRequestEntityTooLarge. 
Splitting {len(artifacts)} updates into two batches.")
+                    _add_artifact(solr, artifacts[:len(artifacts) // 2])
+                    _add_artifact(solr, artifacts[len(artifacts) // 2:])
+                else:
+                    log.info("Solr.add raised HTTPRequestEntityTooLarge but 
there is only one artifact. Raising exception.")
+                    raise
+
+        _add_artifact(__get_solr(solr_hosts), solr_updates)
 
     if len(exceptions) == 1:
         raise exceptions[0][1].with_traceback(exceptions[0][2])
diff --git a/Allura/allura/tests/unit/test_solr.py 
b/Allura/allura/tests/unit/test_solr.py
index 43dccb53d..384a985bf 100644
--- a/Allura/allura/tests/unit/test_solr.py
+++ b/Allura/allura/tests/unit/test_solr.py
@@ -19,6 +19,9 @@ import unittest
 
 import mock
 from markupsafe import Markup
+from pysolr import SolrError
+import pytest
+from webob.exc import HTTPRequestEntityTooLarge
 
 from allura.lib import helpers as h
 from allura.tests import decorators as td
@@ -61,6 +64,15 @@ class TestSolr(unittest.TestCase):
                            commitWithin='10000', somekw='value')] * 2
         pysolr.Solr().add.assert_has_calls(calls)
 
+    @mock.patch('allura.lib.solr.pysolr')
+    def test_add_too_big(self, pysolr):
+        pysolr.Solr.return_value.add.side_effect = \
+            SolrError("Solr responded with an error (HTTP 413): [Reason: 
None]")
+        servers = ['server1', 'server2']
+        solr = Solr(servers, commit=False, commitWithin='10000')
+        with pytest.raises(HTTPRequestEntityTooLarge):
+            solr.add('foo', commit=True, commitWithin=None)
+
     @mock.patch('allura.lib.solr.pysolr')
     def test_delete(self, pysolr):
         servers = ['server1', 'server2']

Reply via email to