Skip to content

Commit cf46b26

Browse files
authored
Merge pull request #5763 from rtfd/hotfix-elastic-master
Try to fix Elastic connection pooling issues
2 parents 2673305 + c9a1752 commit cf46b26

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

readthedocs/search/documents.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from django.conf import settings
44
from django_elasticsearch_dsl import DocType, Index, fields
55

6+
from elasticsearch import Elasticsearch
7+
68
from readthedocs.projects.models import HTMLFile, Project
79
from readthedocs.sphinx_domains.models import SphinxDomain
810

@@ -22,8 +24,19 @@
2224
log = logging.getLogger(__name__)
2325

2426

27+
class RTDDocTypeMixin:
28+
29+
def update(self, *args, **kwargs):
30+
# Hack a fix to our broken connection pooling
31+
# This creates a new connection on every request,
32+
# but actually works :)
33+
log.info('Hacking Elastic indexing to fix connection pooling')
34+
self.using = Elasticsearch(**settings.ELASTICSEARCH_DSL['default'])
35+
super().update(*args, **kwargs)
36+
37+
2538
@domain_index.doc_type
26-
class SphinxDomainDocument(DocType):
39+
class SphinxDomainDocument(RTDDocTypeMixin, DocType):
2740
project = fields.KeywordField(attr='project.slug')
2841
version = fields.KeywordField(attr='version.slug')
2942
role_name = fields.KeywordField(attr='role_name')
@@ -63,7 +76,7 @@ def get_queryset(self):
6376

6477

6578
@project_index.doc_type
66-
class ProjectDocument(DocType):
79+
class ProjectDocument(RTDDocTypeMixin, DocType):
6780

6881
# Metadata
6982
url = fields.TextField(attr='get_absolute_url')
@@ -97,7 +110,7 @@ def faceted_search(cls, query, user, language=None):
97110

98111

99112
@page_index.doc_type
100-
class PageDocument(DocType):
113+
class PageDocument(RTDDocTypeMixin, DocType):
101114

102115
# Metadata
103116
project = fields.KeywordField(attr='project.slug')

readthedocs/search/faceted_search.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import logging
22

3+
from elasticsearch import Elasticsearch
34
from elasticsearch_dsl import FacetedSearch, TermsFacet
45
from elasticsearch_dsl.query import Bool, SimpleQueryString
56

7+
from django.conf import settings
8+
69
from readthedocs.core.utils.extend import SettingsOverrideObject
710
from readthedocs.search.documents import (
811
PageDocument,
@@ -40,6 +43,12 @@ def __init__(self, user, **kwargs):
4043
if f in kwargs:
4144
del kwargs[f]
4245

46+
# Hack a fix to our broken connection pooling
47+
# This creates a new connection on every request,
48+
# but actually works :)
49+
log.info('Hacking Elastic to fix search connection pooling')
50+
self.using = Elasticsearch(**settings.ELASTICSEARCH_DSL['default'])
51+
4352
super().__init__(**kwargs)
4453

4554
def query(self, search, query):

readthedocs/search/signals.py

+11-8
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,17 @@ def remove_indexed_file(sender, instance_list, **kwargs):
6161

6262
if version and commit:
6363
# Sanity check by deleting all old files not in this commit
64-
log.info('Deleting old commits from search index')
65-
document().search().filter(
66-
'term', version=version.slug,
67-
).filter(
68-
'term', project=version.project.slug,
69-
).exclude(
70-
'term', commit=commit,
71-
).delete()
64+
try:
65+
log.info('Deleting old commits from search index')
66+
document().search().filter(
67+
'term', version=version.slug,
68+
).filter(
69+
'term', project=version.project.slug,
70+
).exclude(
71+
'term', commit=commit,
72+
).delete()
73+
except Exception:
74+
log.warning('Unable to delete a subset of files. Continuing.', exc_info=True)
7275

7376

7477
@receiver(post_save, sender=Project)

readthedocs/search/tasks.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ def delete_objects_in_es(app_label, model_name, document_class, objects_id):
6060
queryset = doc_obj.get_queryset()
6161
queryset = queryset.filter(id__in=objects_id)
6262
log.info("Deleting model: %s, '%s' objects", model.__name__, queryset.count())
63-
doc_obj.update(queryset.iterator(), action='delete')
63+
try:
64+
# This is a common case that we should be handling a better way
65+
doc_obj.update(queryset.iterator(), action='delete')
66+
except Exception:
67+
log.warning('Unable to delete a subset of files. Continuing.', exc_info=True)
6468

6569

6670
@app.task(queue='web')

0 commit comments

Comments
 (0)