Example #1
0
 def _update_cache(cls, user_id, course_key, visible_blocks):
     """
     Adds a specific set of visible blocks to the request cache.
     This assumes that prefetch has already been called.
     """
     get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(user_id, course_key)].update(
         {visible_block.hashed: visible_block for visible_block in visible_blocks}
     )
Example #2
0
 def prefetch(cls, course_key, users):
     """
     Prefetches grades for the given users in the given course.
     """
     cache_key = cls._cache_key(course_key)
     get_cache(cls._CACHE_NAMESPACE)[cache_key] = defaultdict(list)
     cached_grades = get_cache(cls._CACHE_NAMESPACE)[cache_key]
     queryset = cls.objects.select_related('visible_blocks', 'override').filter(
         user_id__in=[user.id for user in users],
         course_id=course_key,
     )
     for record in queryset:
         cached_grades[record.user_id].append(record)
Example #3
0
    def __enter__(self):

        connection = transaction.get_connection(self.using)

        cache = get_cache(OUTER_ATOMIC_CACHE_NAME)

        # By default it is enabled.
        enable = True
        # If name is set it is only enabled if requested by calling enable_named_outer_atomic().
        if self.name:
            enable = cache.get(self.name, False)

        if enable:
            # TestCase setup nests tests in two atomics - one for the test class and one for the individual test.
            # The outermost atomic starts a transaction - so does not have a savepoint.
            # The inner atomic starts a savepoint around the test.
            # So, for tests only, there should be exactly one savepoint_id and two atomic_for_testcase_calls.
            # atomic_for_testcase_calls below is added in a monkey-patch for tests only.
            if self.ALLOW_NESTED and (self.atomic_for_testcase_calls - len(connection.savepoint_ids)) < 1:
                raise transaction.TransactionManagementError('Cannot be inside an atomic block.')

            # Otherwise, this shouldn't be nested in any atomic block.
            if not self.ALLOW_NESTED and connection.in_atomic_block:
                raise transaction.TransactionManagementError('Cannot be inside an atomic block.')

            # This will set the transaction isolation level to READ COMMITTED for the next transaction.
            if self.read_committed is True:
                if connection.vendor == 'mysql':
                    cursor = connection.cursor()
                    cursor.execute("SET TRANSACTION ISOLATION LEVEL READ COMMITTED")

        super(OuterAtomic, self).__enter__()
def user_timezone_locale_prefs(request):
    """
    Checks if request has an authenticated user.
    If so, sends set (or none if unset) time_zone and language prefs.

    This interacts with the DateUtils to either display preferred or attempt to determine
    system/browser set time_zones and languages

    """
    cached_value = get_cache(CACHE_NAME)
    if not cached_value:
        user_prefs = {
            'user_timezone': None,
            'user_language': None,
        }
        if hasattr(request, 'user') and request.user.is_authenticated:
            try:
                user_preferences = get_user_preferences(request.user)
            except (UserNotFound, UserAPIInternalError):
                cached_value.update(user_prefs)
            else:
                user_prefs = {
                    key: user_preferences.get(pref_name, None)
                    for key, pref_name in RETRIEVABLE_PREFERENCES.iteritems()
                }

        cached_value.update(user_prefs)
    return cached_value
def get_course_content_milestones(course_id, content_id=None, relationship='requires', user_id=None):
    """
    Client API operation adapter/wrapper
    Uses the request cache to store all of a user's
    milestones

    Returns all content blocks in a course if content_id is None, otherwise it just returns that
    specific content block.
    """
    if not settings.FEATURES.get('MILESTONES_APP'):
        return []

    if user_id is None:
        return milestones_api.get_course_content_milestones(course_id, content_id, relationship)

    request_cache_dict = get_cache(REQUEST_CACHE_NAME)
    if user_id not in request_cache_dict:
        request_cache_dict[user_id] = {}

    if relationship not in request_cache_dict[user_id]:
        request_cache_dict[user_id][relationship] = milestones_api.get_course_content_milestones(
            course_key=course_id,
            relationship=relationship,
            user={"id": user_id}
        )

    if content_id is None:
        return request_cache_dict[user_id][relationship]

    return [m for m in request_cache_dict[user_id][relationship] if m['content_id'] == six.text_type(content_id)]
def create_new_event_transaction_id():
    """
    Sets the event transaction id to a newly-
    generated UUID.
    """
    new_id = uuid4()
    get_cache('event_transaction')['id'] = new_id
    return new_id
def create_new_event_transaction_id():
    """
    Sets the event transaction id to a newly-
    generated UUID.
    """
    new_id = uuid4()
    get_cache('event_transaction')['id'] = new_id
    return new_id
Example #8
0
def set_event_transaction_id(new_id):
    """
    Sets the event transaction id to a UUID object
    generated from new_id.
    new_id must be a parsable string version
    of a UUID.
    """
    get_cache('event_transaction')['id'] = UUID(new_id)
def set_event_transaction_id(new_id):
    """
    Sets the event transaction id to a UUID object
    generated from new_id.
    new_id must be a parsable string version
    of a UUID.
    """
    get_cache('event_transaction')['id'] = UUID(new_id)
Example #10
0
 def prefetch(cls, course_id, users):
     """
     Prefetches grades for the given users for the given course.
     """
     get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(course_id)] = {
         grade.user_id: grade
         for grade in
         cls.objects.filter(user_id__in=[user.id for user in users], course_id=course_id)
     }
Example #11
0
 def prefetch(cls, course_id, users):
     """
     Prefetches grades for the given users for the given course.
     """
     get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(course_id)] = {
         grade.user_id: grade
         for grade in cls.objects.filter(
             user_id__in=[user.id for user in users], course_id=course_id)
     }
Example #12
0
    def prefetch(cls, users):
        roles_by_user = defaultdict(set)
        get_cache(cls.CACHE_NAMESPACE)[cls.CACHE_KEY] = roles_by_user

        for role in CourseAccessRole.objects.filter(user__in=users).select_related('user'):
            roles_by_user[role.user.id].add(role)

        users_without_roles = filter(lambda u: u.id not in roles_by_user, users)
        for user in users_without_roles:
            roles_by_user[user.id] = set()
Example #13
0
    def prefetch(cls, users):
        roles_by_user = defaultdict(set)
        get_cache(cls.CACHE_NAMESPACE)[cls.CACHE_KEY] = roles_by_user

        for role in CourseAccessRole.objects.filter(user__in=users).select_related('user'):
            roles_by_user[role.user.id].add(role)

        users_without_roles = filter(lambda u: u.id not in roles_by_user, users)
        for user in users_without_roles:
            roles_by_user[user.id] = set()
Example #14
0
    def prefetch(cls, users):  # lint-amnesty, pylint: disable=missing-function-docstring
        roles_by_user = defaultdict(set)
        get_cache(cls.CACHE_NAMESPACE)[cls.CACHE_KEY] = roles_by_user

        for role in CourseAccessRole.objects.filter(user__in=users).select_related('user'):
            roles_by_user[role.user.id].add(role)

        users_without_roles = [u for u in users if u.id not in roles_by_user]
        for user in users_without_roles:
            roles_by_user[user.id] = set()
Example #15
0
 def get_override(cls, user_id, usage_key):
     prefetch_values = get_cache(cls._CACHE_NAMESPACE).get((user_id, str(usage_key.course_key)), None)
     if prefetch_values is not None:
         return prefetch_values.get(usage_key)
     try:
         return cls.objects.get(
             grade__user_id=user_id,
             grade__course_id=usage_key.course_key,
             grade__usage_key=usage_key,
         )
     except PersistentSubsectionGradeOverride.DoesNotExist:
         pass
Example #16
0
 def get_override(cls, user_id, usage_key):
     prefetch_values = get_cache(cls._CACHE_NAMESPACE).get((user_id, str(usage_key.course_key)), None)
     if prefetch_values is not None:
         return prefetch_values.get(usage_key)
     try:
         return cls.objects.get(
             grade__user_id=user_id,
             grade__course_id=usage_key.course_key,
             grade__usage_key=usage_key,
         )
     except PersistentSubsectionGradeOverride.DoesNotExist:
         pass
Example #17
0
 def _initialize_cache(cls, user_id, course_key):
     """
     Prefetches visible blocks for the given user and course and stores in the cache.
     Returns a dictionary mapping hashes of these block records to the
     block record objects.
     """
     grades_with_blocks = PersistentSubsectionGrade.objects.select_related('visible_blocks').filter(
         user_id=user_id,
         course_id=course_key,
     )
     prefetched = {grade.visible_blocks.hashed: grade.visible_blocks for grade in grades_with_blocks}
     get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(user_id, course_key)] = prefetched
     return prefetched
Example #18
0
    def bulk_read(cls, user_id, course_key):
        """
        Reads and returns all visible block records for the given user and course from
        the cache.  The cache is initialized with the visible blocks for this user and
        course if no entry currently exists.

        Arguments:
            course_key: The course identifier for the desired records
        """
        prefetched = get_cache(cls._CACHE_NAMESPACE).get(cls._cache_key(user_id, course_key), None)
        if prefetched is None:
            prefetched = cls._initialize_cache(user_id, course_key)
        return prefetched
Example #19
0
 def _initialize_cache(cls, user_id, course_key):
     """
     Prefetches visible blocks for the given user and course and stores in the cache.
     Returns a dictionary mapping hashes of these block records to the
     block record objects.
     """
     grades_with_blocks = PersistentSubsectionGrade.objects.select_related('visible_blocks').filter(
         user_id=user_id,
         course_id=course_key,
     )
     prefetched = {grade.visible_blocks.hashed: grade.visible_blocks for grade in grades_with_blocks}
     get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(user_id, course_key)] = prefetched
     return prefetched
Example #20
0
    def bulk_read(cls, user_id, course_key):
        """
        Reads and returns all visible block records for the given user and course from
        the cache.  The cache is initialized with the visible blocks for this user and
        course if no entry currently exists.

        Arguments:
            course_key: The course identifier for the desired records
        """
        prefetched = get_cache(cls._CACHE_NAMESPACE).get(cls._cache_key(user_id, course_key), None)
        if prefetched is None:
            prefetched = cls._initialize_cache(user_id, course_key)
        return prefetched
Example #21
0
    def prefetch(cls, course_id, users):
        """
        Prefetches the value of the course tags for the specified users
        for the specified course_id.

        Args:
            users: iterator of User objects
            course_id: course identifier (CourseKey)

        Returns:
            course_tags: a dict of dicts,
                where the primary key is the user's id
                and the secondary key is the course tag's key
        """
        course_tags = defaultdict(dict)
        for tag in UserCourseTag.objects.filter(user__in=users, course_id=course_id).select_related('user'):
            course_tags[tag.user.id][tag.key] = tag.value
        get_cache(cls.CACHE_NAMESPACE)[cls._cache_key(course_id)] = course_tags
Example #22
0
def get_current_ccx(course_key):
    """
    Return the ccx that is active for this course.

    course_key is expected to be an instance of an opaque CourseKey, a
    ValueError is raised if this expectation is not met.
    """
    if not isinstance(course_key, CourseKey):
        raise ValueError("get_current_ccx requires a CourseKey instance")

    if not isinstance(course_key, CCXLocator):
        return None

    ccx_cache = get_cache('ccx')
    if course_key not in ccx_cache:
        ccx_cache[course_key] = CustomCourseForEdX.objects.get(pk=course_key.ccx)

    return ccx_cache[course_key]
Example #23
0
    def prefetch(cls, course_id, users):
        """
        Prefetches the value of the course tags for the specified users
        for the specified course_id.

        Args:
            users: iterator of User objects
            course_id: course identifier (CourseKey)

        Returns:
            course_tags: a dict of dicts,
                where the primary key is the user's id
                and the secondary key is the course tag's key
        """
        course_tags = defaultdict(dict)
        for tag in UserCourseTag.objects.filter(user__in=users, course_id=course_id).select_related('user'):
            course_tags[tag.user.id][tag.key] = tag.value
        get_cache(cls.CACHE_NAMESPACE)[cls._cache_key(course_id)] = course_tags
Example #24
0
    def _get_version_info(self, request):
        """
        Gets and Sets version related info in mem cache and request cache; and returns a dict of it.

        It sets request cache data for last_supported_date and latest_version with memcached values if exists against
        user app properties else computes the values for specific platform and sets it in both memcache (for next
        server interaction from same app version/platform) and request cache

        Returns:
            dict: Containing app version info
        """
        user_agent = request.META.get('HTTP_USER_AGENT')
        if user_agent:
            platform = self._get_platform(request, user_agent)
            if platform:
                request_cache_dict = get_cache(self.REQUEST_CACHE_NAME)
                request_cache_dict[self.USER_APP_VERSION] = platform.version
                last_supported_date_cache_key = self._get_cache_key_name(
                    self.LAST_SUPPORTED_DATE_HEADER, platform.version)
                latest_version_cache_key = self._get_cache_key_name(
                    self.LATEST_VERSION_HEADER, platform.NAME)
                cached_data = cache.get_many(
                    [last_supported_date_cache_key, latest_version_cache_key])

                last_supported_date = cached_data.get(
                    last_supported_date_cache_key)
                if last_supported_date != self.NO_LAST_SUPPORTED_DATE and not isinstance(
                        last_supported_date, datetime):
                    last_supported_date = self._get_last_supported_date(
                        platform.NAME, platform.version)
                    cache.set(last_supported_date_cache_key,
                              last_supported_date, self.CACHE_TIMEOUT)
                request_cache_dict[
                    self.LAST_SUPPORTED_DATE_HEADER] = last_supported_date

                latest_version = cached_data.get(latest_version_cache_key)
                if not (latest_version
                        and isinstance(latest_version, six.text_type)):
                    latest_version = self._get_latest_version(platform.NAME)
                    cache.set(latest_version_cache_key, latest_version,
                              self.CACHE_TIMEOUT)
                request_cache_dict[self.LATEST_VERSION_HEADER] = latest_version

                return request_cache_dict
Example #25
0
def get_current_ccx(course_key):
    """
    Return the ccx that is active for this course.

    course_key is expected to be an instance of an opaque CourseKey, a
    ValueError is raised if this expectation is not met.
    """
    if not isinstance(course_key, CourseKey):
        raise ValueError("get_current_ccx requires a CourseKey instance")

    if not isinstance(course_key, CCXLocator):
        return None

    ccx_cache = get_cache('ccx')
    if course_key not in ccx_cache:
        ccx_cache[course_key] = CustomCourseForEdX.objects.get(
            pk=course_key.ccx)

    return ccx_cache[course_key]
Example #26
0
def enable_named_outer_atomic(*names):
    """
    Enable outer_atomics with names.

    Can be used either as a decorator or a context manager.
    See docstring of outer_atomic for details.

    Arguments:
        names (variable-lenght argument list): Names of outer_atomics.
    """
    if len(names) == 0:
        raise ValueError("At least one name must be specified.")

    cache = get_cache(OUTER_ATOMIC_CACHE_NAME)

    for name in names:
        cache[name] = True
    yield
    for name in names:
        del cache[name]
Example #27
0
def enable_named_outer_atomic(*names):
    """
    Enable outer_atomics with names.

    Can be used either as a decorator or a context manager.
    See docstring of outer_atomic for details.

    Arguments:
        names (variable-lenght argument list): Names of outer_atomics.
    """
    if len(names) == 0:
        raise ValueError("At least one name must be specified.")

    cache = get_cache(OUTER_ATOMIC_CACHE_NAME)

    for name in names:
        cache[name] = True
    yield
    for name in names:
        del cache[name]
Example #28
0
def _get_overrides_for_ccx(ccx):
    """
    Returns a dictionary mapping field name to overriden value for any
    overrides set on this block for this CCX.
    """
    overrides_cache = get_cache('ccx-overrides')

    if ccx not in overrides_cache:
        overrides = {}
        query = CcxFieldOverride.objects.filter(ccx=ccx, )

        for override in query:
            block_overrides = overrides.setdefault(override.location, {})
            block_overrides[override.field] = json.loads(override.value)
            block_overrides[override.field + "_id"] = override.id
            block_overrides[override.field + "_instance"] = override

        overrides_cache[ccx] = overrides

    return overrides_cache[ccx]
Example #29
0
    def process_response(self, __, response):
        """
        If request is from mobile native app, then add version related info to response headers.

        Returns:
            Http response: with additional headers;
                1. EDX-APP-LATEST-VERSION; if user app version < latest available version
                2. EDX-APP-VERSION-LAST-SUPPORTED-DATE; if user app version < min supported version and
                   timestamp < expiry of that version
        """
        request_cache_dict = get_cache(self.REQUEST_CACHE_NAME)
        if request_cache_dict:
            last_supported_date = request_cache_dict[self.LAST_SUPPORTED_DATE_HEADER]
            if last_supported_date != self.NO_LAST_SUPPORTED_DATE:
                response[self.LAST_SUPPORTED_DATE_HEADER] = last_supported_date.isoformat()
            latest_version = request_cache_dict[self.LATEST_VERSION_HEADER]
            user_app_version = request_cache_dict[self.USER_APP_VERSION]
            if (latest_version != self.NO_LATEST_VERSION and
                    parsed_version(user_app_version) < parsed_version(latest_version)):
                response[self.LATEST_VERSION_HEADER] = latest_version
        return response
Example #30
0
    def read(cls, user_id, course_id):
        """
        Reads a grade from database

        Arguments:
            user_id: The user associated with the desired grade
            course_id: The id of the course associated with the desired grade

        Raises PersistentCourseGrade.DoesNotExist if applicable
        """
        try:
            prefetched_grades = get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(course_id)]
            try:
                return prefetched_grades[user_id]
            except KeyError:
                # user's grade is not in the prefetched dict, so
                # assume they have no grade
                raise cls.DoesNotExist
        except KeyError:
            # grades were not prefetched for the course, so fetch it
            return cls.objects.get(user_id=user_id, course_id=course_id)
Example #31
0
    def process_response(self, __, response):
        """
        If request is from mobile native app, then add version related info to response headers.

        Returns:
            Http response: with additional headers;
                1. EDX-APP-LATEST-VERSION; if user app version < latest available version
                2. EDX-APP-VERSION-LAST-SUPPORTED-DATE; if user app version < min supported version and
                   timestamp < expiry of that version
        """
        request_cache_dict = get_cache(self.REQUEST_CACHE_NAME)
        if request_cache_dict:
            last_supported_date = request_cache_dict[self.LAST_SUPPORTED_DATE_HEADER]
            if last_supported_date != self.NO_LAST_SUPPORTED_DATE:
                response[self.LAST_SUPPORTED_DATE_HEADER] = last_supported_date.isoformat()
            latest_version = request_cache_dict[self.LATEST_VERSION_HEADER]
            user_app_version = request_cache_dict[self.USER_APP_VERSION]
            if (latest_version != self.NO_LATEST_VERSION and
                    parsed_version(user_app_version) < parsed_version(latest_version)):
                response[self.LATEST_VERSION_HEADER] = latest_version
        return response
Example #32
0
    def read(cls, user_id, course_id):
        """
        Reads a grade from database

        Arguments:
            user_id: The user associated with the desired grade
            course_id: The id of the course associated with the desired grade

        Raises PersistentCourseGrade.DoesNotExist if applicable
        """
        try:
            prefetched_grades = get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(course_id)]
            try:
                return prefetched_grades[user_id]
            except KeyError:
                # user's grade is not in the prefetched dict, so
                # assume they have no grade
                raise cls.DoesNotExist
        except KeyError:
            # grades were not prefetched for the course, so fetch it
            return cls.objects.get(user_id=user_id, course_id=course_id)
Example #33
0
    def bulk_read_grades(cls, user_id, course_key):
        """
        Reads all grades for the given user and course.

        Arguments:
            user_id: The user associated with the desired grades
            course_key: The course identifier for the desired grades
        """
        try:
            prefetched_grades = get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(course_key)]
            try:
                return prefetched_grades[user_id]
            except KeyError:
                # The user's grade is not in the cached dict of subsection grades,
                # so return an empty list.
                return []
        except KeyError:
            # subsection grades were not prefetched for the course, so get them from the DB
            return cls.objects.select_related('visible_blocks', 'override').filter(
                user_id=user_id,
                course_id=course_key,
            )
Example #34
0
    def bulk_read_grades(cls, user_id, course_key):
        """
        Reads all grades for the given user and course.

        Arguments:
            user_id: The user associated with the desired grades
            course_key: The course identifier for the desired grades
        """
        try:
            prefetched_grades = get_cache(cls._CACHE_NAMESPACE)[cls._cache_key(course_key)]
            try:
                return prefetched_grades[user_id]
            except KeyError:
                # The user's grade is not in the cached dict of subsection grades,
                # so return an empty list.
                return []
        except KeyError:
            # subsection grades were not prefetched for the course, so get them from the DB
            return cls.objects.select_related('visible_blocks', 'override').filter(
                user_id=user_id,
                course_id=course_key,
            )
Example #35
0
def _get_overrides_for_ccx(ccx):
    """
    Returns a dictionary mapping field name to overriden value for any
    overrides set on this block for this CCX.
    """
    overrides_cache = get_cache('ccx-overrides')

    if ccx not in overrides_cache:
        overrides = {}
        query = CcxFieldOverride.objects.filter(
            ccx=ccx,
        )

        for override in query:
            block_overrides = overrides.setdefault(override.location, {})
            block_overrides[override.field] = json.loads(override.value)
            block_overrides[override.field + "_id"] = override.id
            block_overrides[override.field + "_instance"] = override

        overrides_cache[ccx] = overrides

    return overrides_cache[ccx]
Example #36
0
    def _get_version_info(self, request):
        """
        Gets and Sets version related info in mem cache and request cache; and returns a dict of it.

        It sets request cache data for last_supported_date and latest_version with memcached values if exists against
        user app properties else computes the values for specific platform and sets it in both memcache (for next
        server interaction from same app version/platform) and request cache

        Returns:
            dict: Containing app version info
        """
        user_agent = request.META.get('HTTP_USER_AGENT')
        if user_agent:
            platform = self._get_platform(request, user_agent)
            if platform:
                request_cache_dict = get_cache(self.REQUEST_CACHE_NAME)
                request_cache_dict[self.USER_APP_VERSION] = platform.version
                last_supported_date_cache_key = self._get_cache_key_name(
                    self.LAST_SUPPORTED_DATE_HEADER,
                    platform.version
                )
                latest_version_cache_key = self._get_cache_key_name(self.LATEST_VERSION_HEADER, platform.NAME)
                cached_data = cache.get_many([last_supported_date_cache_key, latest_version_cache_key])

                last_supported_date = cached_data.get(last_supported_date_cache_key)
                if not last_supported_date:
                    last_supported_date = self._get_last_supported_date(platform.NAME, platform.version)
                    cache.set(last_supported_date_cache_key, last_supported_date, self.CACHE_TIMEOUT)
                request_cache_dict[self.LAST_SUPPORTED_DATE_HEADER] = last_supported_date

                latest_version = cached_data.get(latest_version_cache_key)
                if not latest_version:
                    latest_version = self._get_latest_version(platform.NAME)
                    cache.set(latest_version_cache_key, latest_version, self.CACHE_TIMEOUT)
                request_cache_dict[self.LATEST_VERSION_HEADER] = latest_version

                return request_cache_dict
def get_course_content_milestones(course_id,
                                  content_id=None,
                                  relationship='requires',
                                  user_id=None):
    """
    Client API operation adapter/wrapper
    Uses the request cache to store all of a user's
    milestones

    Returns all content blocks in a course if content_id is None, otherwise it just returns that
    specific content block.
    """
    if not ENABLE_MILESTONES_APP.is_enabled():
        return []

    if user_id is None:
        return milestones_api.get_course_content_milestones(
            course_id, content_id, relationship)

    request_cache_dict = get_cache(REQUEST_CACHE_NAME)
    if user_id not in request_cache_dict:
        request_cache_dict[user_id] = {}

    if relationship not in request_cache_dict[user_id]:
        request_cache_dict[user_id][
            relationship] = milestones_api.get_course_content_milestones(
                course_key=course_id,
                relationship=relationship,
                user={"id": user_id})

    if content_id is None:
        return request_cache_dict[user_id][relationship]

    return [
        m for m in request_cache_dict[user_id][relationship]
        if m['content_id'] == str(content_id)
    ]
Example #38
0
    def __enter__(self):

        connection = transaction.get_connection(self.using)

        cache = get_cache(OUTER_ATOMIC_CACHE_NAME)

        # By default it is enabled.
        enable = True
        # If name is set it is only enabled if requested by calling enable_named_outer_atomic().
        if self.name:
            enable = cache.get(self.name, False)

        if enable:
            # TestCase setup nests tests in two atomics - one for the test class and one for the individual test.
            # The outermost atomic starts a transaction - so does not have a savepoint.
            # The inner atomic starts a savepoint around the test.
            # So, for tests only, there should be exactly one savepoint_id and two atomic_for_testcase_calls.
            # atomic_for_testcase_calls below is added in a monkey-patch for tests only.
            if self.ALLOW_NESTED and (self.atomic_for_testcase_calls -
                                      len(connection.savepoint_ids)) < 1:
                raise transaction.TransactionManagementError(
                    'Cannot be inside an atomic block.')

            # Otherwise, this shouldn't be nested in any atomic block.
            if not self.ALLOW_NESTED and connection.in_atomic_block:
                raise transaction.TransactionManagementError(
                    'Cannot be inside an atomic block.')

            # This will set the transaction isolation level to READ COMMITTED for the next transaction.
            if self.read_committed is True:
                if connection.vendor == 'mysql':
                    cursor = connection.cursor()
                    cursor.execute(
                        "SET TRANSACTION ISOLATION LEVEL READ COMMITTED")

        super(OuterAtomic, self).__enter__()
Example #39
0
 def cached_get_or_create(cls, user_id, blocks):
     """
     Given a ``user_id`` and a ``BlockRecordList`` object, attempts to
     fetch the related VisibleBlocks model from the request cache.  This
     will create and save a new ``VisibleBlocks`` record if no record
     exists corresponding to the hash_value of ``blocks``.
     """
     prefetched = get_cache(cls._CACHE_NAMESPACE).get(cls._cache_key(user_id, blocks.course_key))
     if prefetched is not None:
         model = prefetched.get(blocks.hash_value)
         if not model:
             # We still have to do a get_or_create, because
             # another user may have had this block hash created,
             # even if the user we checked the cache for hasn't yet.
             model, _ = cls.objects.get_or_create(
                 hashed=blocks.hash_value, blocks_json=blocks.json_value, course_id=blocks.course_key,
             )
             cls._update_cache(user_id, blocks.course_key, [model])
     else:
         model, _ = cls.objects.get_or_create(
             hashed=blocks.hash_value,
             defaults={u'blocks_json': blocks.json_value, u'course_id': blocks.course_key},
         )
     return model
Example #40
0
 def cached_get_or_create(cls, user_id, blocks):
     """
     Given a ``user_id`` and a ``BlockRecordList`` object, attempts to
     fetch the related VisibleBlocks model from the request cache.  This
     will create and save a new ``VisibleBlocks`` record if no record
     exists corresponding to the hash_value of ``blocks``.
     """
     prefetched = get_cache(cls._CACHE_NAMESPACE).get(cls._cache_key(user_id, blocks.course_key))
     if prefetched is not None:
         model = prefetched.get(blocks.hash_value)
         if not model:
             # We still have to do a get_or_create, because
             # another user may have had this block hash created,
             # even if the user we checked the cache for hasn't yet.
             model, _ = cls.objects.get_or_create(
                 hashed=blocks.hash_value, blocks_json=blocks.json_value, course_id=blocks.course_key,
             )
             cls._update_cache(user_id, blocks.course_key, [model])
     else:
         model, _ = cls.objects.get_or_create(
             hashed=blocks.hash_value,
             defaults={u'blocks_json': blocks.json_value, u'course_id': blocks.course_key},
         )
     return model
Example #41
0
 def clear_prefetched_data(cls, course_key):
     """
     Clears prefetched grades for this course from the RequestCache.
     """
     get_cache(cls._CACHE_NAMESPACE).pop(cls._cache_key(course_key), None)
Example #42
0
 def _update_cache(cls, course_id, user_id, grade):
     course_cache = get_cache(cls._CACHE_NAMESPACE).get(
         cls._cache_key(course_id))
     if course_cache is not None:
         course_cache[user_id] = grade
Example #43
0
 def prefetch(cls, user_id, course_key):
     get_cache(cls._CACHE_NAMESPACE)[(user_id, str(course_key))] = {
         override.grade.usage_key: override
         for override in
         cls.objects.filter(grade__user_id=user_id, grade__course_id=course_key)
     }
Example #44
0
 def is_prefetched(cls, course_id):
     return cls._cache_key(course_id) in get_cache(cls.CACHE_NAMESPACE)
Example #45
0
 def _update_cache(cls, course_id, user_id, grade):
     course_cache = get_cache(cls._CACHE_NAMESPACE).get(cls._cache_key(course_id))
     if course_cache is not None:
         course_cache[user_id] = grade
Example #46
0
 def get_user_roles(cls, user):
     return get_cache(cls.CACHE_NAMESPACE)[cls.CACHE_KEY][user.id]
Example #47
0
 def get_course_tag(cls, user_id, course_id, key):
     return get_cache(cls.CACHE_NAMESPACE)[cls._cache_key(course_id)][user_id][key]
Example #48
0
 def is_prefetched(cls, course_id):
     return cls._cache_key(course_id) in get_cache(cls.CACHE_NAMESPACE)
def set_event_transaction_type(action_type):
    """
    Takes a string and stores it in the request cache
    as the user action type.
    """
    get_cache('event_transaction')['type'] = action_type
def get_event_transaction_id():
    """
    Retrieves the current event transaction id from the request
    cache.
    """
    return get_cache('event_transaction').get('id', None)
def get_event_transaction_type():
    """
    Retrieves the current event transaction type from the request
    cache.
    """
    return get_cache('event_transaction').get('type', None)
Example #52
0
 def clear_prefetched_data(cls, course_key):
     """
     Clears prefetched grades for this course from the RequestCache.
     """
     get_cache(cls._CACHE_NAMESPACE).pop(cls._cache_key(course_key), None)
Example #53
0
 def get_user_roles(cls, user):
     return get_cache(cls.CACHE_NAMESPACE)[cls.CACHE_KEY][user.id]
Example #54
0
 def prefetch(cls, user_id, course_key):
     get_cache(cls._CACHE_NAMESPACE)[(user_id, str(course_key))] = {
         override.grade.usage_key: override
         for override in cls.objects.filter(grade__user_id=user_id,
                                            grade__course_id=course_key)
     }
Example #55
0
 def get_course_tag(cls, user_id, course_id, key):
     return get_cache(cls.CACHE_NAMESPACE)[cls._cache_key(course_id)][user_id][key]