-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #162 from modoboa/fix/slow_perf_manual_learning
Enabled asynchronous learning from user using RQ
- Loading branch information
Showing
5 changed files
with
123 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
"""Async tasks.""" | ||
|
||
from typing import List | ||
|
||
from django.utils.translation import ngettext | ||
|
||
from modoboa.core import models as core_models | ||
|
||
from .lib import SpamassassinClient | ||
from .sql_connector import SQLconnector | ||
|
||
|
||
def manual_learning(user_pk: int, | ||
mtype: str, | ||
selection: List[str], | ||
recipient_db: str): | ||
"""Task to trigger manual learning for given selection.""" | ||
user = core_models.User.objects.get(pk=user_pk) | ||
connector = SQLconnector() | ||
saclient = SpamassassinClient(user, recipient_db) | ||
for item in selection: | ||
rcpt, mail_id = item.split() | ||
content = connector.get_mail_content(mail_id.encode("ascii")) | ||
result = saclient.learn_spam(rcpt, content) if mtype == "spam" \ | ||
else saclient.learn_ham(rcpt, content) | ||
if not result: | ||
break | ||
connector.set_msgrcpt_status( | ||
rcpt, mail_id, mtype[0].upper() | ||
) | ||
if saclient.error is None: | ||
saclient.done() | ||
message = ngettext("%(count)d message processed successfully", | ||
"%(count)d messages processed successfully", | ||
len(selection)) % {"count": len(selection)} | ||
else: | ||
message = saclient.error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,11 +5,15 @@ | |
import os | ||
from unittest import mock | ||
|
||
from rq import SimpleWorker | ||
|
||
from django.core import mail | ||
from django.core.management import call_command | ||
from django.test import override_settings | ||
from django.urls import reverse | ||
|
||
import django_rq | ||
|
||
from modoboa.admin import factories as admin_factories | ||
from modoboa.core import models as core_models | ||
from modoboa.lib.tests import ModoTestCase | ||
|
@@ -226,7 +230,10 @@ def _test_mark_message(self, action, status): | |
data = {"rcpt": smart_str(self.msgrcpt.rid.email)} | ||
response = self.ajax_post(url, data) | ||
self.assertEqual( | ||
response["message"], "1 message processed successfully") | ||
response["message"], "Your request is being processed...") | ||
queue = django_rq.get_queue("default") | ||
worker = SimpleWorker([queue], connection=queue.connection) | ||
worker.work(burst=True) | ||
self.msgrcpt.refresh_from_db() | ||
self.assertEqual(self.msgrcpt.rs, status) | ||
|
||
|
@@ -235,7 +242,8 @@ def _test_mark_message(self, action, status): | |
self.set_global_parameter("sa_is_local", False) | ||
response = self.ajax_post(url, data) | ||
self.assertEqual( | ||
response["message"], "1 message processed successfully") | ||
response["message"], "Your request is being processed...") | ||
worker.work(burst=True) | ||
self.msgrcpt.refresh_from_db() | ||
self.assertEqual(self.msgrcpt.rs, status) | ||
|
||
|
@@ -289,7 +297,7 @@ def test_manual_learning_as_user(self): | |
self._test_mark_message("ham", "H") | ||
|
||
@mock.patch("socket.socket") | ||
def test_process(self, mock_socket): | ||
def test_process_release(self, mock_socket): | ||
"""Test process mode (bulk).""" | ||
# Initiate session | ||
url = reverse("modoboa_amavis:_mail_list") | ||
|
@@ -305,8 +313,9 @@ def test_process(self, mock_socket): | |
smart_str(msgrcpt.rid.email), | ||
smart_str(msgrcpt.mail.mail_id)), | ||
] | ||
mock_socket.return_value.recv.side_effect = ( | ||
b"250 1234 Ok\r\n", b"250 1234 Ok\r\n") | ||
mock_socket.return_value.recv.side_effect = [ | ||
b"250 1234 Ok\r\n", b"250 1234 Ok\r\n" | ||
] | ||
data = { | ||
"action": "release", | ||
"rcpt": smart_str(self.msgrcpt.rid.email), | ||
|
@@ -317,15 +326,36 @@ def test_process(self, mock_socket): | |
self.assertEqual( | ||
response["message"], "2 messages released successfully") | ||
|
||
def test_process_all(self): | ||
"""Test process mode (bulk).""" | ||
# Initiate session | ||
url = reverse("modoboa_amavis:_mail_list") | ||
response = self.ajax_get(url) | ||
|
||
msgrcpt = factories.create_spam("[email protected]") | ||
url = reverse("modoboa_amavis:mail_process") | ||
selection = [ | ||
"{} {}".format( | ||
smart_str(self.msgrcpt.rid.email), | ||
smart_str(self.msgrcpt.mail.mail_id)), | ||
"{} {}".format( | ||
smart_str(msgrcpt.rid.email), | ||
smart_str(msgrcpt.mail.mail_id)), | ||
] | ||
data = { | ||
"rcpt": smart_str(self.msgrcpt.rid.email), | ||
"selection": ",".join(selection) | ||
} | ||
|
||
data["action"] = "mark_as_spam" | ||
response = self.ajax_post(url, data) | ||
self.assertEqual( | ||
response["message"], "2 messages processed successfully") | ||
response["message"], "Your request is being processed...") | ||
|
||
data["action"] = "mark_as_ham" | ||
response = self.ajax_post(url, data) | ||
self.assertEqual( | ||
response["message"], "2 messages processed successfully") | ||
response["message"], "Your request is being processed...") | ||
|
||
data = { | ||
"action": "delete", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters