Skip to content

Commit 77398d7

Browse files
committed
feat: implement XqueueViewSet with full xqueue-watcher compatibility
- Add XqueueViewSet with complete xqueue-watcher service compatibility - Implement get_submission service for retrieving pending submissions - Add put_result service with row-level locking (select_for_update(nowait=True)) to prevent race conditions - Ensure concurrent xqueue-watcher instances process each submission exactly once, even under high load - Implement standardized response format for backward compatibility - Add session management and authentication handling for XWatcher clients - Add comprehensive test coverage for core interactions
1 parent f7d55d7 commit 77398d7

7 files changed

Lines changed: 999 additions & 1 deletion

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
3. Implementation of XQueue Compatible Views for External Grader Integration
2+
############################################################################
3+
4+
Status
5+
******
6+
7+
**Provisional** *2025-02-21*
8+
9+
Implemented by https://github.com/openedx/edx-submissions/pull/284
10+
11+
Context
12+
*******
13+
14+
Following the creation of ExternalGraderDetail (ADR 1) and SubmissionFile (ADR 2) models, we need to implement the API
15+
endpoints that will allow external graders (XWatcher) to interact with the system. The current XQueue implementation
16+
provides three critical endpoints that need to be replicated:
17+
18+
1. Authentication Service:
19+
- Secure login mechanism for external graders
20+
- Session management
21+
- CSRF handling for specific endpoints
22+
23+
2. Submission Retrieval (get_submission):
24+
- Queue-based submission distribution
25+
- Status tracking and locking mechanism
26+
- File information packaging for graders
27+
28+
3. Result Processing (put_result):
29+
- Score validation and processing
30+
- Status updates
31+
- Error handling and retry mechanisms
32+
33+
The current XQueue implementation has these services spread across multiple systems, requiring complex HTTP communication
34+
and session management. The existing workflow:
35+
36+
1. Authentication Flow:
37+
- Basic username/password authentication
38+
- Session-based token management
39+
- Manual CSRF handling for specific endpoints
40+
41+
2. Submission Processing:
42+
- Manual queue status checks
43+
- Complex state transitions
44+
- Synchronous HTTP-based file retrieval
45+
46+
3. Result Handling:
47+
- Direct database updates
48+
- Limited error recovery
49+
- Complex retry logic
50+
51+
Decision
52+
********
53+
54+
We will implement a unified service approach that brings together all the functionality needed for external grader integration. This approach will:
55+
56+
1. Simplify Authentication:
57+
- Create a more straightforward login process for external graders
58+
- Make session handling more reliable
59+
- Ensure security while reducing technical complexity
60+
61+
2. Improve Submission Handling:
62+
- Create a more efficient way to distribute submissions to graders
63+
- Track the status of submissions more reliably
64+
- Provide all necessary information to graders in a consistent format
65+
66+
3. Enhance Results Processing:
67+
- Process scores more reliably
68+
- Handle errors gracefully
69+
- Provide better feedback to both graders and the platform
70+
71+
The solution will be built as a consolidated service that external graders can interact with through standard REST API endpoints. This will make integration easier for external services while providing better monitoring and control for the platform.
72+
73+
Key Benefits:
74+
75+
1. External graders will have a single, consistent interface
76+
2. The platform will have better visibility into the grading process
77+
3. Error handling will be improved across the entire workflow
78+
4. Security will be enhanced through better authentication practices
79+
80+
This approach connects directly with the previously created data models for external graders and submission files, providing a complete end-to-end solution for the grading workflow.
81+
82+
Consequences
83+
************
84+
85+
Positive:
86+
---------
87+
88+
1. Architecture:
89+
- Consolidated service endpoints
90+
- Clean separation of concerns
91+
- Improved error handling
92+
- Better session management
93+
94+
2. Security:
95+
- Robust authentication
96+
- Secure file handling
97+
- Protected state transitions
98+
99+
3. Operations:
100+
- Simplified deployment
101+
- Better monitoring capabilities
102+
- Improved error visibility
103+
- Automatic retry handling
104+
105+
Negative:
106+
---------
107+
108+
1. Complexity:
109+
- More complex session management
110+
- Additional state validation required
111+
- Complex transaction handling
112+
113+
2. Performance:
114+
- Additional database operations
115+
- Session verification overhead
116+
117+
3. Migration:
118+
- Changes required in external graders
119+
- New deployment procedures needed
120+
121+
References
122+
**********
123+
124+
Implementation References:
125+
126+
* XQueue ViewSet Implementation: Link to PR
127+
* External Grader Integration Guide: Link to documentation
128+
129+
Related ADRs:
130+
131+
* ADR 1: Creation of ExternalGraderDetail Model
132+
* ADR 2: File Handling Implementation
133+
134+
Documentation:
135+
136+
* XQueue API Specification
137+
* External Grader Integration Guide
138+
* Session Management Documentation
139+
140+
Architecture Guidelines:
141+
142+
* Django REST Framework Best Practices
143+
* Open edX API Guidelines

submissions/serializers.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from rest_framework import serializers
99
from rest_framework.fields import DateTimeField, Field, IntegerField
1010

11-
from submissions.models import Score, ScoreAnnotation, StudentItem, Submission, TeamSubmission
11+
from submissions.models import ExternalGraderDetail, Score, ScoreAnnotation, StudentItem, Submission, TeamSubmission
1212

1313

1414
class RawField(Field):
@@ -221,3 +221,18 @@ class Meta:
221221
'submission_uuid',
222222
'annotations',
223223
)
224+
225+
226+
class SubmissionListSerializer(serializers.ModelSerializer):
227+
class Meta:
228+
model = Submission
229+
fields = '__all__'
230+
231+
232+
class ExternalGraderDetailSerializer(serializers.ModelSerializer):
233+
""" Serializer for ExternalGraderDetail """
234+
submission = SubmissionListSerializer(read_only=True)
235+
236+
class Meta:
237+
model = ExternalGraderDetail
238+
fields = '__all__'

submissions/tests/factories.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
import factory
66
from django.contrib import auth
7+
from django.utils import timezone
78
from django.utils.timezone import now
89
from factory.django import DjangoModelFactory
910
from pytz import UTC
1011

1112
from submissions import models
13+
from submissions.models import ExternalGraderDetail
1214

1315
User = auth.get_user_model()
1416

@@ -71,3 +73,18 @@ class Meta:
7173
item_id = factory.Faker('sha1')
7274
team_id = factory.Faker('sha1')
7375
submitted_by = factory.SubFactory(UserFactory)
76+
77+
78+
class ExternalGraderDetailFactory(DjangoModelFactory):
79+
"""
80+
Factory for the ExternalGraderDetail model.
81+
"""
82+
class Meta:
83+
model = ExternalGraderDetail
84+
85+
submission = factory.SubFactory(SubmissionFactory)
86+
pullkey = factory.Sequence(lambda n: f'test_pull_key_{n}')
87+
status = 'pending'
88+
num_failures = 0
89+
grader_reply = ''
90+
status_time = factory.LazyFunction(timezone.now)

0 commit comments

Comments
 (0)