Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB - 466] perf: improve performance for cycle and module endpoints #3711

Merged
merged 24 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bac8aeb
dev: improve performance for cycle apis
pablohashescobar Feb 19, 2024
042cc31
dev: reduce module endpoints and create a new endpoint for getting is…
pablohashescobar Feb 19, 2024
12374e8
dev: remove unwanted fields from module
pablohashescobar Feb 19, 2024
c3ef3ca
dev: update module endpoints
pablohashescobar Feb 19, 2024
199d50d
dev: optimize cycle endpoints
pablohashescobar Feb 19, 2024
701500d
change module and cycle types
rahulramesha Feb 19, 2024
7a0a12f
dev: module optimizations
pablohashescobar Feb 19, 2024
251284f
Merge branch 'perf/cycle-module-endpoints' of github.com:makeplane/pl…
rahulramesha Feb 19, 2024
27cc4c8
dev: fix the issues check
pablohashescobar Feb 19, 2024
0e8258d
Merge branch 'perf/cycle-module-endpoints' of github.com:makeplane/pl…
rahulramesha Feb 19, 2024
f89e415
dev: fix issues endpoint
pablohashescobar Feb 19, 2024
98cfc50
dev: update module detail serializer
pablohashescobar Feb 19, 2024
7078863
Merge branch 'perf/cycle-module-endpoints' of github.com:makeplane/pl…
rahulramesha Feb 20, 2024
fa085bd
modify adding issues to modules and cycles
rahulramesha Feb 20, 2024
fdb0563
dev: update cycle issues
pablohashescobar Feb 20, 2024
dfbc262
fix module links
rahulramesha Feb 20, 2024
de2baf2
dev: optimize issue list endpoint
pablohashescobar Feb 20, 2024
e65db66
Merge branch 'develop' of gurusainath:makeplane/plane into perf/cycle…
gurusainath Feb 20, 2024
a6acdc1
Merge branch 'perf/cycle-module-endpoints' of github.com:makeplane/pl…
pablohashescobar Feb 20, 2024
0183268
fix: removing issues from the module when removing module_id from iss…
gurusainath Feb 20, 2024
4bf7ea9
Merge branch 'perf/cycle-module-endpoints' of gurusainath:makeplane/p…
gurusainath Feb 20, 2024
50fb15b
Merge branch 'develop' of gurusainath:makeplane/plane into perf/cycle…
gurusainath Feb 20, 2024
035edf3
fix: updated the tooltip and ui for cycle select (#3718)
gurusainath Feb 20, 2024
27cf553
fix: updated the tooltip and ui for module select (#3716)
gurusainath Feb 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apiserver/plane/app/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
)

from .module import (
ModuleDetailSerializer,
ModuleWriteSerializer,
ModuleSerializer,
ModuleIssueSerializer,
Expand Down
82 changes: 35 additions & 47 deletions apiserver/plane/app/serializers/cycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@

# Module imports
from .base import BaseSerializer
from .user import UserLiteSerializer
from .issue import IssueStateSerializer
from .workspace import WorkspaceLiteSerializer
from .project import ProjectLiteSerializer
from plane.db.models import (
Cycle,
CycleIssue,
CycleFavorite,
CycleUserProperties,
)


class CycleWriteSerializer(BaseSerializer):
def validate(self, data):
if (
Expand All @@ -30,65 +26,57 @@ def validate(self, data):
class Meta:
model = Cycle
fields = "__all__"
read_only_fields = [
"workspace",
"project",
"owned_by",
]


class CycleSerializer(BaseSerializer):
# favorite
is_favorite = serializers.BooleanField(read_only=True)
total_issues = serializers.IntegerField(read_only=True)
# state group wise distribution
cancelled_issues = serializers.IntegerField(read_only=True)
completed_issues = serializers.IntegerField(read_only=True)
started_issues = serializers.IntegerField(read_only=True)
unstarted_issues = serializers.IntegerField(read_only=True)
backlog_issues = serializers.IntegerField(read_only=True)
assignees = serializers.SerializerMethodField(read_only=True)
total_estimates = serializers.IntegerField(read_only=True)
completed_estimates = serializers.IntegerField(read_only=True)
started_estimates = serializers.IntegerField(read_only=True)
workspace_detail = WorkspaceLiteSerializer(
read_only=True, source="workspace"
)
project_detail = ProjectLiteSerializer(read_only=True, source="project")
status = serializers.CharField(read_only=True)

def validate(self, data):
if (
data.get("start_date", None) is not None
and data.get("end_date", None) is not None
and data.get("start_date", None) > data.get("end_date", None)
):
raise serializers.ValidationError(
"Start date cannot exceed end date"
)
return data

def get_assignees(self, obj):
members = [
{
"avatar": assignee.avatar,
"display_name": assignee.display_name,
"id": assignee.id,
}
for issue_cycle in obj.issue_cycle.prefetch_related(
"issue__assignees"
).all()
for assignee in issue_cycle.issue.assignees.all()
]
# Use a set comprehension to return only the unique objects
unique_objects = {frozenset(item.items()) for item in members}

# Convert the set back to a list of dictionaries
unique_list = [dict(item) for item in unique_objects]
# active | draft | upcoming | completed
status = serializers.CharField(read_only=True)

return unique_list

class Meta:
model = Cycle
fields = "__all__"
read_only_fields = [
"workspace",
"project",
"owned_by",
fields = [
# necessary fields
"id",
"workspace_id",
"project_id",
# model fields
"name",
"description",
"start_date",
"end_date",
"owned_by_id",
"view_props",
"sort_order",
"external_source",
"external_id",
"progress_snapshot",
# meta fields
"is_favorite",
"total_issues",
"cancelled_issues",
"completed_issues",
"started_issues",
"unstarted_issues",
"backlog_issues",
"status",
]
read_only_fields = fields


class CycleIssueSerializer(BaseSerializer):
Expand Down
75 changes: 51 additions & 24 deletions apiserver/plane/app/serializers/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from .base import BaseSerializer, DynamicBaseSerializer
from .user import UserLiteSerializer
from .project import ProjectLiteSerializer
from .workspace import WorkspaceLiteSerializer

from plane.db.models import (
User,
Expand All @@ -19,17 +18,18 @@


class ModuleWriteSerializer(BaseSerializer):
members = serializers.ListField(
lead_id = serializers.PrimaryKeyRelatedField(
source="lead",
queryset=User.objects.all(),
required=False,
allow_null=True,
)
member_ids = serializers.ListField(
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.all()),
write_only=True,
required=False,
)

project_detail = ProjectLiteSerializer(source="project", read_only=True)
workspace_detail = WorkspaceLiteSerializer(
source="workspace", read_only=True
)

class Meta:
model = Module
fields = "__all__"
Expand All @@ -44,7 +44,9 @@ class Meta:

def to_representation(self, instance):
data = super().to_representation(instance)
data["members"] = [str(member.id) for member in instance.members.all()]
data["member_ids"] = [
str(member.id) for member in instance.members.all()
]
return data

def validate(self, data):
Expand All @@ -59,12 +61,10 @@ def validate(self, data):
return data

def create(self, validated_data):
members = validated_data.pop("members", None)

members = validated_data.pop("member_ids", None)
project = self.context["project"]

module = Module.objects.create(**validated_data, project=project)

if members is not None:
ModuleMember.objects.bulk_create(
[
Expand All @@ -85,7 +85,7 @@ def create(self, validated_data):
return module

def update(self, instance, validated_data):
members = validated_data.pop("members", None)
members = validated_data.pop("member_ids", None)

if members is not None:
ModuleMember.objects.filter(module=instance).delete()
Expand Down Expand Up @@ -142,7 +142,6 @@ class Meta:


class ModuleLinkSerializer(BaseSerializer):
created_by_detail = UserLiteSerializer(read_only=True, source="created_by")

class Meta:
model = ModuleLink
Expand Down Expand Up @@ -170,12 +169,9 @@ def create(self, validated_data):


class ModuleSerializer(DynamicBaseSerializer):
project_detail = ProjectLiteSerializer(read_only=True, source="project")
lead_detail = UserLiteSerializer(read_only=True, source="lead")
members_detail = UserLiteSerializer(
read_only=True, many=True, source="members"
member_ids = serializers.ListField(
child=serializers.UUIDField(), required=False, allow_null=True
)
link_module = ModuleLinkSerializer(read_only=True, many=True)
is_favorite = serializers.BooleanField(read_only=True)
total_issues = serializers.IntegerField(read_only=True)
cancelled_issues = serializers.IntegerField(read_only=True)
Expand All @@ -186,15 +182,46 @@ class ModuleSerializer(DynamicBaseSerializer):

class Meta:
model = Module
fields = "__all__"
read_only_fields = [
"workspace",
"project",
"created_by",
"updated_by",
fields = [
# Required fields
"id",
"workspace_id",
"project_id",
# Model fields
"name",
"description",
"description_text",
"description_html",
"start_date",
"target_date",
"status",
"lead_id",
"member_ids",
"view_props",
"sort_order",
"external_source",
"external_id",
# computed fields
"is_favorite",
"total_issues",
"cancelled_issues",
"completed_issues",
"started_issues",
"unstarted_issues",
"backlog_issues",
"created_at",
"updated_at",
]
read_only_fields = fields



class ModuleDetailSerializer(ModuleSerializer):

link_module = ModuleLinkSerializer(read_only=True, many=True)

class Meta(ModuleSerializer.Meta):
fields = ModuleSerializer.Meta.fields + ['link_module']


class ModuleFavoriteSerializer(BaseSerializer):
Expand Down
6 changes: 6 additions & 0 deletions apiserver/plane/app/urls/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


from plane.app.views import (
IssueListEndpoint,
IssueViewSet,
LabelViewSet,
BulkCreateIssueLabelsEndpoint,
Expand All @@ -25,6 +26,11 @@


urlpatterns = [
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/list/",
IssueListEndpoint.as_view(),
name="project-issue",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/",
IssueViewSet.as_view(
Expand Down
1 change: 1 addition & 0 deletions apiserver/plane/app/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
)
from .asset import FileAssetEndpoint, UserAssetsEndpoint, FileAssetViewSet
from .issue import (
IssueListEndpoint,
IssueViewSet,
WorkSpaceIssuesEndpoint,
IssueActivityEndpoint,
Expand Down
Loading
Loading