Add indexes for Stator and some of its common tasks (#332)

This commit is contained in:
Michael Manfre 2023-01-01 12:58:13 -05:00 committed by GitHub
parent 43ba09a16e
commit 5f1d7b5253
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 195 additions and 3 deletions

View file

@ -0,0 +1,84 @@
# Generated by Django 4.1.4 on 2023-01-01 17:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("activities", "0007_post_stats"),
]
operations = [
migrations.AddIndex(
model_name="fanout",
index=models.Index(
fields=["state", "state_attempted"], name="ix_fanout_state_attempted"
),
),
migrations.AddIndex(
model_name="fanout",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_fanout_state_locked",
),
),
migrations.AddIndex(
model_name="hashtag",
index=models.Index(
fields=["state", "state_attempted"], name="ix_hashtag_state_attempted"
),
),
migrations.AddIndex(
model_name="hashtag",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_hashtag_state_locked",
),
),
migrations.AddIndex(
model_name="post",
index=models.Index(
fields=["visibility", "local", "published"],
name="ix_post_local_public_published",
),
),
migrations.AddIndex(
model_name="post",
index=models.Index(
fields=["visibility", "local", "created"],
name="ix_post_local_public_created",
),
),
migrations.AddIndex(
model_name="post",
index=models.Index(
fields=["state", "state_attempted"], name="ix_post_state_attempted"
),
),
migrations.AddIndex(
model_name="post",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_post_state_locked",
),
),
migrations.AddIndex(
model_name="postattachment",
index=models.Index(
fields=["state", "state_attempted"],
name="ix_postattachm_state_attempted",
),
),
migrations.AddIndex(
model_name="postattachment",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_postattachm_state_locked",
),
),
]

View file

@ -297,6 +297,14 @@ class Post(StatorModel):
class Meta:
indexes = [
GinIndex(fields=["hashtags"], name="hashtags_gin"),
models.Index(
fields=["visibility", "local", "published"],
name="ix_post_local_public_published",
),
models.Index(
fields=["visibility", "local", "created"],
name="ix_post_local_public_created",
),
]
class urls(urlman.Urls):

View file

@ -4,6 +4,7 @@ from typing import ClassVar, cast
from asgiref.sync import sync_to_async
from django.db import models, transaction
from django.db.models.signals import class_prepared
from django.utils import timezone
from django.utils.functional import classproperty
@ -37,6 +38,40 @@ class StateField(models.CharField):
return value
def add_stator_indexes(sender, **kwargs):
"""
Inject Indexes used by StatorModel in to any subclasses. This sidesteps the
current Django inability to inherit indexes when the Model subclass defines
its own indexes.
"""
if issubclass(sender, StatorModel):
indexes = [
models.Index(
fields=["state", "state_attempted"],
name=f"ix_{sender.__name__.lower()[:11]}_state_attempted",
),
models.Index(
fields=["state_locked_until", "state"],
condition=models.Q(state_locked_until__isnull=False),
name=f"ix_{sender.__name__.lower()[:11]}_state_locked",
),
]
if not sender._meta.indexes:
# Meta.indexes needs to not be None to trigger Django behaviors
sender.Meta.indexes = []
for idx in indexes:
sender._meta.indexes.append(idx)
# class_prepared might become deprecated [1]. If it's removed, the named Index
# injection would need to happen in a metaclass subclass of ModelBase's _prepare()
#
# [1] https://code.djangoproject.com/ticket/24313
class_prepared.connect(add_stator_indexes)
class StatorModel(models.Model):
"""
A model base class that has a state machine backing it, with tasks to work

View file

@ -14,8 +14,7 @@ class Migration(migrations.Migration):
model_name="follow",
name="boosts",
field=models.BooleanField(
default=True,
help_text="Also follow boosts from this user",
default=True, help_text="Also follow boosts from this user"
),
),
]

View file

@ -0,0 +1,66 @@
# Generated by Django 4.1.4 on 2023-01-01 17:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("users", "0008_follow_boosts"),
]
operations = [
migrations.AlterField(
model_name="identity",
name="restriction",
field=models.IntegerField(
choices=[(0, "None"), (1, "Limited"), (2, "Blocked")],
db_index=True,
default=0,
),
),
migrations.AddIndex(
model_name="inboxmessage",
index=models.Index(
fields=["state", "state_attempted"],
name="ix_inboxmessag_state_attempted",
),
),
migrations.AddIndex(
model_name="inboxmessage",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_inboxmessag_state_locked",
),
),
migrations.AddIndex(
model_name="passwordreset",
index=models.Index(
fields=["state", "state_attempted"],
name="ix_passwordres_state_attempted",
),
),
migrations.AddIndex(
model_name="passwordreset",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_passwordres_state_locked",
),
),
migrations.AddIndex(
model_name="report",
index=models.Index(
fields=["state", "state_attempted"], name="ix_report_state_attempted"
),
),
migrations.AddIndex(
model_name="report",
index=models.Index(
condition=models.Q(("state_locked_until__isnull", False)),
fields=["state_locked_until", "state"],
name="ix_report_state_locked",
),
),
]

View file

@ -203,7 +203,7 @@ class Identity(StatorModel):
# Admin-only moderation fields
sensitive = models.BooleanField(default=False)
restriction = models.IntegerField(
choices=Restriction.choices, default=Restriction.none
choices=Restriction.choices, default=Restriction.none, db_index=True
)
admin_notes = models.TextField(null=True, blank=True)