Commit 1d4d81c2 by Diana Huang

Make the launch callback polling interval variable.

parent 14d6164c
...@@ -23,6 +23,9 @@ from edx_proctoring.api import ( ...@@ -23,6 +23,9 @@ from edx_proctoring.api import (
from edx_proctoring.backends import get_backend_provider from edx_proctoring.backends import get_backend_provider
from edx_proctoring.exceptions import ProctoredBaseException from edx_proctoring.exceptions import ProctoredBaseException
from edx_proctoring.models import ProctoredExamStudentAttemptStatus from edx_proctoring.models import ProctoredExamStudentAttemptStatus
from edx_proctoring.utils import get_time_remaining_for_attempt
from edx_proctoring import constants
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -154,12 +157,17 @@ class AttemptStatus(APIView): ...@@ -154,12 +157,17 @@ class AttemptStatus(APIView):
) )
update_exam_attempt(attempt['id'], last_poll_timestamp=timestamp, last_poll_ipaddr=ip_address) update_exam_attempt(attempt['id'], last_poll_timestamp=timestamp, last_poll_ipaddr=ip_address)
time_remaining_seconds = get_time_remaining_for_attempt(attempt)
polling_interval = constants.DEFAULT_CLIENT_POLLING_INTERVAL
if time_remaining_seconds < constants.EXAM_CONCLUDING_INTERVAL:
polling_interval = constants.REDUCED_CLIENT_POLLING_INTERVAL
return Response( return Response(
data={ data={
# IMPORTANT: Don't add more information to this as it is an # IMPORTANT: Don't add more information to this as it is an
# unauthenticated endpoint # unauthenticated endpoint
'status': attempt['status'], 'status': attempt['status'],
'polling_interval': polling_interval,
}, },
status=200 status=200
) )
...@@ -46,7 +46,7 @@ REQUIRE_FAILURE_SECOND_REVIEWS = ( ...@@ -46,7 +46,7 @@ REQUIRE_FAILURE_SECOND_REVIEWS = (
SOFTWARE_SECURE_CLIENT_TIMEOUT = ( SOFTWARE_SECURE_CLIENT_TIMEOUT = (
settings.PROCTORING_SETTINGS['SOFTWARE_SECURE_CLIENT_TIMEOUT'] if settings.PROCTORING_SETTINGS['SOFTWARE_SECURE_CLIENT_TIMEOUT'] if
'SOFTWARE_SECURE_CLIENT_TIMEOUT' in settings.PROCTORING_SETTINGS 'SOFTWARE_SECURE_CLIENT_TIMEOUT' in settings.PROCTORING_SETTINGS
else getattr(settings, 'SOFTWARE_SECURE_CLIENT_TIMEOUT', 30) else getattr(settings, 'SOFTWARE_SECURE_CLIENT_TIMEOUT', 60)
) )
SOFTWARE_SECURE_SHUT_DOWN_GRACEPERIOD = ( SOFTWARE_SECURE_SHUT_DOWN_GRACEPERIOD = (
...@@ -55,4 +55,23 @@ SOFTWARE_SECURE_SHUT_DOWN_GRACEPERIOD = ( ...@@ -55,4 +55,23 @@ SOFTWARE_SECURE_SHUT_DOWN_GRACEPERIOD = (
else getattr(settings, 'SOFTWARE_SECURE_SHUT_DOWN_GRACEPERIOD', 10) else getattr(settings, 'SOFTWARE_SECURE_SHUT_DOWN_GRACEPERIOD', 10)
) )
DEFAULT_CLIENT_POLLING_INTERVAL = (
settings.PROCTORING_SETTINGS['DEFAULT_CLIENT_POLLING_INTERVAL'] if
'DEFAULT_CLIENT_POLLING_INTERVAL' in settings.PROCTORING_SETTINGS
else getattr(settings, 'DEFAULT_CLIENT_POLLING_INTERVAL', 30)
)
REDUCED_CLIENT_POLLING_INTERVAL = (
settings.PROCTORING_SETTINGS['REDUCED_CLIENT_POLLING_INTERVAL'] if
'REDUCED_CLIENT_POLLING_INTERVAL' in settings.PROCTORING_SETTINGS
else getattr(settings, 'REDUCED_CLIENT_POLLING_INTERVAL', 10)
)
EXAM_CONCLUDING_INTERVAL = (
settings.PROCTORING_SETTINGS['EXAM_CONCLUDING_INTERVAL'] if
'EXAM_CONCLUDING_INTERVAL' in settings.PROCTORING_SETTINGS
else getattr(settings, 'EXAM_CONCLUDING_INTERVAL', 180)
)
MINIMUM_TIME = datetime.datetime.fromtimestamp(0) MINIMUM_TIME = datetime.datetime.fromtimestamp(0)
...@@ -190,10 +190,7 @@ ...@@ -190,10 +190,7 @@
var _poll_interval = null; var _poll_interval = null;
$(document).ready(function() { $(document).ready(function() {
_poll_interval = setInterval( poll_exam_status();
poll_exam_status,
5000
);
}); });
function poll_exam_status() { function poll_exam_status() {
...@@ -206,6 +203,9 @@ ...@@ -206,6 +203,9 @@
// NOTE: This is per the API documentation from SoftwareSecure // NOTE: This is per the API documentation from SoftwareSecure
window.external.quitApplication(); window.external.quitApplication();
} }
clearInterval(_poll_interval);
// The polling interval is returned in seconds, so we need to multiply by 1000.
_poll_interval = setInterval(poll_exam_status, parseInt(data.polling_interval) * 1000);
}); });
} }
......
...@@ -36,6 +36,7 @@ from .utils import ( ...@@ -36,6 +36,7 @@ from .utils import (
LoggedInTestCase LoggedInTestCase
) )
from edx_proctoring import constants
from edx_proctoring.urls import urlpatterns from edx_proctoring.urls import urlpatterns
from edx_proctoring.backends.tests.test_review_payload import TEST_REVIEW_PAYLOAD from edx_proctoring.backends.tests.test_review_payload import TEST_REVIEW_PAYLOAD
from edx_proctoring.backends.tests.test_software_secure import mock_response_content from edx_proctoring.backends.tests.test_software_secure import mock_response_content
...@@ -836,6 +837,29 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase): ...@@ -836,6 +837,29 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@patch('edx_proctoring.callbacks.get_time_remaining_for_attempt')
def test_attempt_status_poll_interval(self, time_remaining_mock):
"""
Test that the poll interval is correct depending on the amount of time remaining.
"""
exam_attempt = self._create_exam_attempt()
# test the polling callback point
polling_status_endpoint = reverse(
'edx_proctoring.anonymous.proctoring_poll_status',
args=[exam_attempt.attempt_code]
)
# When the exam has not reached the concluding interval.
time_remaining_mock.return_value = constants.EXAM_CONCLUDING_INTERVAL + 5
response = self.client.get(polling_status_endpoint)
response_data = json.loads(response.content)
self.assertEqual(response_data['polling_interval'], constants.DEFAULT_CLIENT_POLLING_INTERVAL)
time_remaining_mock.return_value = constants.EXAM_CONCLUDING_INTERVAL - 5
response = self.client.get(polling_status_endpoint)
response_data = json.loads(response.content)
self.assertEqual(response_data['polling_interval'], constants.REDUCED_CLIENT_POLLING_INTERVAL)
def test_attempt_status_stickiness(self): def test_attempt_status_stickiness(self):
""" """
Test to confirm that a status timeout error will not alter a completed state Test to confirm that a status timeout error will not alter a completed state
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment