Skip to content

Commit

Permalink
feat: improve translation propagation performance
Browse files Browse the repository at this point in the history
Bulk update units and create changes instead of doing all the operations
manually. This should considerable reduce time needed for propagation,
but still there is some time to be spent on checks.
  • Loading branch information
nijel committed Nov 21, 2024
1 parent 0bd113e commit da4e8ed
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 19 deletions.
2 changes: 2 additions & 0 deletions docs/admin/continuous.rst
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ Keeping translations same across components
Once you have multiple translation components, you might want to ensure that
the same strings have same translation. This can be achieved at several levels.

.. _translation-propagation:

Translation propagation
+++++++++++++++++++++++

Expand Down
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Not yet released.
* Editor in :ref:`zen-mode` is now stick to bottom of screen.
* Added page navigation while :ref:`translating`.
* :ref:`manage-appearance` now has distinct settings for dark mode.
* Improved :ref:`translation-propagation` performance.

**Bug fixes**
* Using the `has:variant` field now correctly displays strings that have variant(s) in the search language, see :ref:`search-strings`.
Expand Down
71 changes: 52 additions & 19 deletions weblate/trans/models/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ def propagate(self, user: User, change_action=None, author=None, request=None):
"""Propagate current translation to all others."""
from weblate.auth.permissions import PermissionResult

result = False
to_update: list[Unit] = []
for unit in self.same_source_units:
if unit.target == self.target and unit.state == self.state:
continue
Expand All @@ -1057,15 +1057,32 @@ def propagate(self, user: User, change_action=None, author=None, request=None):
continue
unit.target = self.target
unit.state = self.state
unit.save_backend(
user,
propagate=False,
change_action=change_action,
author=None,
run_checks=False,
)
result = True
return result
unit.commit_if_pending(user)
to_update.append(unit)

if not to_update:
return False

# Bulk update units
Unit.objects.filter(pk__in=(unit.pk for unit in to_update)).update(
target=self.target,
state=self.state,
last_updated=self.last_updated,
)

# Postprocess changes and generate change objects
changes = [
unit.post_save(user, user, None, check_new=False, save=False)
for unit in to_update
]

# Bulk create changes
Change.objects.bulk_create(changes)

# Update user stats
user.profile.increase_count("translated", len(to_update))

return True

def commit_if_pending(self, author: User) -> None:
"""Commit possible previous changes on this unit."""
Expand Down Expand Up @@ -1141,8 +1158,28 @@ def save_backend(
propagate_checks=was_propagated or changed,
)

# Generate change and process it
self.post_save(user or author, author, change_action)

# Update related source strings if working on a template
if self.translation.is_template and self.old_unit["target"] != self.target:
self.update_source_units(self.old_unit["target"], user or author, author)

return True

def post_save(
self,
user: User,
author: User | None,
change_action: int | None,
*,
save: bool = True,
check_new: bool = True,
) -> Change:
# Generate Change object for this change
change = self.generate_change(user or author, author, change_action)
change = self.generate_change(
user or author, author, change_action, save=save, check_new=check_new
)

if change.action not in {
Change.ACTION_UPLOAD,
Expand All @@ -1164,13 +1201,9 @@ def save_backend(
)

# Update user stats
change.author.profile.increase_count("translated")

# Update related source strings if working on a template
if self.translation.is_template and self.old_unit["target"] != self.target:
self.update_source_units(self.old_unit["target"], user or author, author)

return True
if save:
change.author.profile.increase_count("translated")
return change

def update_source_units(
self, previous_source: str, user: User, author: User | None
Expand Down Expand Up @@ -1229,7 +1262,7 @@ def generate_change(
self,
user: User | None,
author: User | None,
change_action: int,
change_action: int | None,
*,
check_new: bool = True,
save: bool = True,
Expand Down

0 comments on commit da4e8ed

Please sign in to comment.