2017-11-16 00:55:49 +01:00
|
|
|
import cProfile
|
|
|
|
import logging
|
2019-01-15 02:58:03 +01:00
|
|
|
import tempfile
|
2021-08-18 18:42:39 +02:00
|
|
|
from typing import Any
|
2013-06-19 20:24:16 +02:00
|
|
|
|
2021-08-14 16:51:57 +02:00
|
|
|
from django.contrib.sessions.backends.base import SessionBase
|
2017-07-18 02:02:59 +02:00
|
|
|
from django.core.management.base import CommandParser
|
2023-05-11 02:34:34 +02:00
|
|
|
from django.http import HttpRequest, HttpResponseBase
|
2023-10-12 19:43:45 +02:00
|
|
|
from typing_extensions import override
|
2017-11-16 00:55:49 +01:00
|
|
|
|
2017-07-18 02:02:59 +02:00
|
|
|
from zerver.lib.management import ZulipBaseCommand
|
2021-08-21 19:24:20 +02:00
|
|
|
from zerver.lib.request import RequestNotes
|
2021-08-14 16:51:57 +02:00
|
|
|
from zerver.lib.test_helpers import HostRequestMock
|
2017-11-16 00:55:49 +01:00
|
|
|
from zerver.middleware import LogRequests
|
2021-08-18 18:42:39 +02:00
|
|
|
from zerver.models import UserMessage
|
2020-06-22 23:32:53 +02:00
|
|
|
from zerver.views.message_fetch import get_messages_backend
|
2013-06-19 20:24:16 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2021-08-18 18:42:39 +02:00
|
|
|
class MockSession(SessionBase):
|
2017-10-27 12:57:54 +02:00
|
|
|
def __init__(self) -> None:
|
2013-06-19 20:24:16 +02:00
|
|
|
self.modified = False
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2024-06-09 13:10:17 +02:00
|
|
|
def profile_request(request: HttpRequest, num_before: int, num_after: int) -> HttpResponseBase:
|
2023-05-11 02:34:34 +02:00
|
|
|
def get_response(request: HttpRequest) -> HttpResponseBase:
|
2024-06-09 13:10:17 +02:00
|
|
|
return prof.runcall(
|
|
|
|
get_messages_backend,
|
|
|
|
request,
|
|
|
|
request.user,
|
|
|
|
num_before=num_before,
|
|
|
|
num_after=num_after,
|
|
|
|
apply_markdown=True,
|
|
|
|
)
|
2022-01-14 03:23:49 +01:00
|
|
|
|
2013-06-19 20:24:16 +02:00
|
|
|
prof = cProfile.Profile()
|
2021-02-12 08:20:45 +01:00
|
|
|
with tempfile.NamedTemporaryFile(prefix="profile.data.", delete=False) as stats_file:
|
2022-01-14 03:23:49 +01:00
|
|
|
response = LogRequests(get_response)(request)
|
2023-07-19 23:31:19 +02:00
|
|
|
assert isinstance(response, HttpResponseBase) # async responses not supported here for now
|
2019-01-15 02:58:03 +01:00
|
|
|
prof.dump_stats(stats_file.name)
|
2020-05-02 08:44:14 +02:00
|
|
|
logging.info("Profiling data written to %s", stats_file.name)
|
2022-01-14 03:23:49 +01:00
|
|
|
return response
|
2013-06-19 20:24:16 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2017-07-18 02:02:59 +02:00
|
|
|
class Command(ZulipBaseCommand):
|
2023-10-12 19:43:45 +02:00
|
|
|
@override
|
2017-10-27 12:57:54 +02:00
|
|
|
def add_arguments(self, parser: CommandParser) -> None:
|
2020-09-02 21:24:05 +02:00
|
|
|
parser.add_argument("email", metavar="<email>", help="Email address of the user")
|
2017-07-18 02:02:59 +02:00
|
|
|
self.add_realm_args(parser)
|
2013-06-19 20:24:16 +02:00
|
|
|
|
2023-10-12 19:43:45 +02:00
|
|
|
@override
|
2017-10-27 12:57:54 +02:00
|
|
|
def handle(self, *args: Any, **options: Any) -> None:
|
2017-07-18 02:02:59 +02:00
|
|
|
realm = self.get_realm(options)
|
|
|
|
user = self.get_user(options["email"], realm)
|
2021-08-18 18:42:39 +02:00
|
|
|
anchor = UserMessage.objects.filter(user_profile=user).order_by("-message")[200].message_id
|
|
|
|
mock_request = HostRequestMock(
|
|
|
|
post_data={
|
|
|
|
"anchor": anchor,
|
|
|
|
"num_before": 1200,
|
|
|
|
"num_after": 200,
|
|
|
|
},
|
|
|
|
user_profile=user,
|
|
|
|
meta_data={"REMOTE_ADDR": "127.0.0.1"},
|
|
|
|
path="/",
|
|
|
|
)
|
|
|
|
mock_request.session = MockSession()
|
2021-08-21 19:24:20 +02:00
|
|
|
RequestNotes.get_notes(mock_request).log_data = None
|
2021-08-18 18:42:39 +02:00
|
|
|
|
2024-06-09 13:10:17 +02:00
|
|
|
profile_request(mock_request, num_before=1200, num_after=200)
|