Skip to content

Commit

Permalink
Merge pull request #219 from lihuacai168/feat/mock-log-perf
Browse files Browse the repository at this point in the history
feat: mock perf using cache
  • Loading branch information
lihuacai168 committed Jun 16, 2024
2 parents 1b2b685 + b5f7adb commit ce4234b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 29 deletions.
2 changes: 1 addition & 1 deletion FasterRunner/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
BROKER_URL = "amqp://username:password@localhost:5672//"
# 需要先在RabbitMQ上创建fast_dev这个vhost

broker_url = "amqp://admin:111111@192.168.22.19:5672/fast_dev"
broker_url = "amqp://rabbitMQ_username:rabbitMQ_password@localhost:5672/fast_dev"


BASE_REPORT_URL = "http://localhost:8000/api/fastrunner/reports"
Expand Down
32 changes: 16 additions & 16 deletions docker-compose-build-db-mq.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ x-env: &env
MQ_ADMIN_PORT: ${MQ_ADMIN_PORT}

services:
db:
#image: mysql:8.0.21
image: mariadb:10.6.1
# privileged: true
environment:
# 设置默认数据库和root默认密码,如果宿主机中/var/lib/mysql已经存在,这两个设置都不会生效
<<: *env
volumes:
# - "/var/lib/mysql:/var/lib/mysql" # 挂载宿主机的mysql数据到docker中
- ./db/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
- ./db:/docker-entrypoint-initdb.d/:ro
# 端口映射,格式 宿主机端口:容器端口
ports:
- "${MYSQL_PORT_OUT}:3306"
restart: always
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# db:
# #image: mysql:8.0.21
# image: mariadb:10.6.1
# # privileged: true
# environment:
# # 设置默认数据库和root默认密码,如果宿主机中/var/lib/mysql已经存在,这两个设置都不会生效
# <<: *env
# volumes:
## - "/var/lib/mysql:/var/lib/mysql" # 挂载宿主机的mysql数据到docker中
# - ./db/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
# - ./db:/docker-entrypoint-initdb.d/:ro
# # 端口映射,格式 宿主机端口:容器端口
# ports:
# - "${MYSQL_PORT_OUT}:3306"
# restart: always
# command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci


mq:
Expand Down
10 changes: 6 additions & 4 deletions fastrunner/utils/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def process_request(self, request):
request._body = request.body

def process_response(self, request, response):
url: str = request.path
# 去除测试报告页字体相关的访问
if "/fonts/roboto/" in url or url.startswith('/mock/'):
return response

body = request._body
if body == b"":
body = ""
Expand All @@ -34,10 +39,7 @@ def process_response(self, request, response):
# 前端请求头没传project,就默认为0
project = request.headers.get("project", 0)

url: str = request.path
# 去除测试报告页字体相关的访问
if "/fonts/roboto/" in url:
return response


if request.GET != {}:
query_params = "?"
Expand Down
17 changes: 17 additions & 0 deletions mock/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# tasks.py
from celery import shared_task
from mock.models import MockAPILog


@shared_task
def log_mock_api(request_obj, request_id, api_id, project_id, req_time, response_obj):
log_obj = MockAPILog.objects.create(
request_obj=request_obj,
request_id=request_id,
api_id=api_id,
project_id=project_id,
create_time=req_time
)
log_obj.response_obj = response_obj
log_obj.save()
return log_obj.id
48 changes: 40 additions & 8 deletions mock/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import traceback
import types
import uuid
from collections import defaultdict
from datetime import datetime


from django_filters import rest_framework as filters
from django_filters.rest_framework import DjangoFilterBackend
from drf_yasg.utils import swagger_auto_schema
Expand All @@ -19,9 +19,28 @@
from FasterRunner.customer_swagger import CustomSwaggerAutoSchema
from .models import MockAPI, MockAPILog, MockProject
from .serializers import MockAPISerializer, MockProjectSerializer, MockAPILogSerializer
from .tasks import log_mock_api

logger = logging.getLogger(__name__)

# 全局字典用于缓存
mock_api_cache = defaultdict(dict)


def fetch_mock_api(project_id, path, method):
key = (project_id, path, method)
if key in mock_api_cache:
return mock_api_cache[key]
else:
mock_api = MockAPI.objects.get(
project__project_id=project_id,
request_path=path,
request_method=method,
is_active=True
)
mock_api_cache[key] = mock_api
return mock_api


# mock function demo
def execute(req, resp):
Expand Down Expand Up @@ -86,7 +105,7 @@ def update(self, request, *args, **kwargs):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}

mock_api_cache.pop((instance.project.project_id, instance.request_path, instance.request_method), None)
return Response(serializer.data)


Expand Down Expand Up @@ -164,6 +183,7 @@ def convert_to_kv(input_dict):
return {value[0]: value[1] for key, value in input_dict.items()}



def process(path, project_id, request: Request):
try:
req_time = datetime.now()
Expand All @@ -181,12 +201,16 @@ def process(path, project_id, request: Request):
if settings.IS_PERF == '0':
logger.info(f"request_obj: {json.dumps(request_obj, indent=4)}")

mock_api = MockAPI.objects.get(
project__project_id=project_id,
request_path=path,
request_method=request.method.upper(),
is_active=True,
)
if settings.IS_PERF == '1':
mock_api = fetch_mock_api(project_id, path, request.method.upper())
else:
mock_api = MockAPI.objects.get(
project__project_id=project_id,
request_path=path,
request_method=request.method.upper(),
is_active=True,
)

request_id: str = uuid.uuid4().hex

response = load_and_execute(
Expand All @@ -200,6 +224,14 @@ def process(path, project_id, request: Request):
}
if settings.IS_PERF == '0':
logger.info(f"response_obj: {json.dumps(response_obj, indent=4)}")
# log_mock_api.delay(
# request_obj=request_obj,
# request_id=request_id,
# api_id=mock_api.api_id,
# project_id=mock_api.project.project_id,
# req_time=req_time,
# response_obj=response_obj
# )
log_obj = MockAPILog.objects.create(
request_obj=request_obj,
request_id=request_id,
Expand Down

0 comments on commit ce4234b

Please sign in to comment.