Ejemplo n.º 1
0
    def after_put(self, *args, **kwargs):
        if self.tasklist:
            # Tasklist might not always be present; it is if created via
            # create(), but not if fetched from the datastore.
            self.tasklist.put()

        # Reset memcache for cached properties of related objects.
        # This relationship is "down" so there may be many keys to clear so
        # don't try to actually refresh the cached values, just set up a cache
        # miss for their next read and they'll recover.
        to_delete = []

        for pc in model.ProjectCohort.get(n=float('inf'), project_id=self.uid):
            # These keys are for individual project cohort entities.
            to_delete.append(util.cached_properties_key(pc.uid))
            # These are for caches of whole query results.
            kwargs = {
                'program_label': pc.program_label,
                'cohort_label': pc.cohort_label
            }
            to_delete.append(util.cached_query_key('SuperDashboard', **kwargs))
            taskqueue.add(
                url='/task/cache_dashboard',
                headers={'Content-Type': 'application/json; charset=utf-8'},
                payload=json.dumps(kwargs),
                countdown=config.task_consistency_countdown,
            )
        # Also clear the dashboard's organization query.
        to_delete.append(
            util.cached_query_key('SuperDashboard',
                                  organization_id=self.organization_id))

        memcache.delete_multi(to_delete)
Ejemplo n.º 2
0
    def test_put_clears_dashboard_queries(self):
        org, project, pc = self.create_org_with_pc()

        org_key = util.cached_query_key(
            'SuperDashboard',
            organization_id=org.uid,
        )
        program_cohort_key = util.cached_query_key(
            'SuperDashboard',
            program_label=pc.program_label,
            cohort_label=pc.cohort_label,
        )
        memcache.set(org_key, {'foo': 1})
        memcache.set(program_cohort_key, {'foo': 1})
        self.assertEqual(memcache.get(program_cohort_key), {'foo': 1})

        # Re-fetch the org so it doesn't have an associated tasklist, which
        # saves checkpoints. This should clear memcache without relying on those
        # checkpoints.
        org = org.key.get()
        org.name = "Bar University"
        org.put()

        self.assertIsNone(memcache.get(org_key))
        self.assertIsNone(memcache.get(program_cohort_key))
Ejemplo n.º 3
0
    def test_put_clears_dashboard_queries(self):
        pc = ProjectCohort.create(
            program_label='demo-program',
            organization_id='Organization_Foo',
            project_id='Project_Foo',
            cohort_label='2018',
        )

        org_key = util.cached_query_key(
            'SuperDashboard',
            organization_id=pc.organization_id,
        )
        program_cohort_key = util.cached_query_key(
            'SuperDashboard',
            program_label=pc.program_label,
            cohort_label=pc.cohort_label,
        )

        memcache.set(org_key, {'foo': 1})
        memcache.set(program_cohort_key, {'foo': 1})

        # This should clear memcache.
        pc.put()

        self.assertIsNone(memcache.get(org_key))
        self.assertIsNone(memcache.get(program_cohort_key))
Ejemplo n.º 4
0
    def after_put(self, *args, **kwargs):
        # On changes to any org, clear the cached list of names.
        for p in self.public_properties:
            memcache.delete(self.all_of_property_key(p))

        # Reset memcache for cached properties of related objects and queries.
        # This relationship is "down" so there may be many keys to clear so
        # don't try to actually refresh the cached values, just set up a cache
        # miss for their next read and they'll recover.
        to_delete = []

        # Projects
        p_keys = model.Project.get(n=float('inf'),
                                   organization_id=self.uid,
                                   keys_only=True)
        # These keys are for individual project entities
        to_delete += [util.cached_properties_key(k.id()) for k in p_keys]

        # ProjectCohorts
        pcs = list(
            model.ProjectCohort.get(n=float('inf'), organization_id=self.uid)
        )  # force generator to store whole list in memory for re-use
        # These keys are for individual project cohort entities
        to_delete += [util.cached_properties_key(pc.uid) for pc in pcs]
        # These are for caches of whole query results.
        to_delete += [
            util.cached_query_key('SuperDashboard', organization_id=self.uid)
        ]
        for pc in pcs:
            kwargs = {
                'program_label': pc.program_label,
                'cohort_label': pc.cohort_label
            }
            to_delete.append(util.cached_query_key('SuperDashboard', **kwargs))
            taskqueue.add(
                url='/task/cache_dashboard',
                headers={'Content-Type': 'application/json; charset=utf-8'},
                payload=json.dumps(kwargs),
                countdown=config.task_consistency_countdown,
            )

        memcache.delete_multi(to_delete)

        # Save tasklist.
        if self.tasklist:
            # Tasklist might not always be present; it is if created via
            # create(), but not if fetched from the datastore.
            self.tasklist.put()
Ejemplo n.º 5
0
    def test_put_clears_dashboard_queries(self):
        org_id = 'Organization_Foo'
        program_label = 'demo-program'
        pc = ProjectCohort.create(
            program_label='demo-program',
            organization_id=org_id,
            project_id='Project_Foo',
            cohort_label='2018',
        )
        pc.put()
        program_config = Program.get_config(program_label)
        template = program_config['surveys'][0]['survey_tasklist_template']
        survey = Survey.create(
            template,
            program_label=program_label,
            organization_id=org_id,
            project_cohort_id=pc.uid,
            ordinal=1,
        )
        survey.put()

        org_key = util.cached_query_key(
            'SuperDashboard',
            organization_id=pc.organization_id,
        )
        program_cohort_key = util.cached_query_key(
            'SuperDashboard',
            program_label=pc.program_label,
            cohort_label=pc.cohort_label,
        )

        memcache.set(org_key, {'foo': 1})
        memcache.set(program_cohort_key, {'foo': 1})

        # Re-fetch the org so it doesn't have an associated tasklist, which
        # saves checkpoints. This should clear memcache without relying on those
        # checkpoints.
        survey = survey.key.get()
        survey.status = 'ready'
        survey.put()

        self.assertIsNone(memcache.get(org_key))
        self.assertIsNone(memcache.get(program_cohort_key))
Ejemplo n.º 6
0
    def after_put(self, *args, **kwargs):
        """Clear any cached queries related to this."""
        kwargs = {
            'program_label': self.program_label,
            'cohort_label': self.cohort_label
        }
        to_delete = [
            util.cached_query_key('SuperDashboard',
                                  organization_id=self.organization_id),
            util.cached_query_key('SuperDashboard', **kwargs),
        ]
        taskqueue.add(
            url='/task/cache_dashboard',
            headers={'Content-Type': 'application/json; charset=utf-8'},
            payload=json.dumps(kwargs),
            countdown=config.task_consistency_countdown,
        )

        memcache.delete_multi(to_delete)
Ejemplo n.º 7
0
    def after_put(self, init_kwargs):
        """Reset memcache for cached properties of related objects

        This is a bit tricky, because org or project checkpoints may be cached
        on many different project cohorts, while survey checkpoints will only
        ever be cached on one.
        """

        # First clear cached properties on whatever project cohorts are related.
        # Collect them for later.
        pcs = []
        if self.parent_kind == 'Organization':
            pcs += self.clear_cached_properties('organization_id')
        elif self.parent_kind == 'Project':
            pcs += self.clear_cached_properties('project_id')
        elif self.parent_kind == 'Survey':
            # This relationship is "up" so there's only one thing to update.
            # Take the time to refresh the cache value instead of just clearing.
            pc = model.ProjectCohort.get_by_id(self.project_cohort_id)
            if pc:
                pc.update_cached_properties()
                pcs.append(pc)

        # Then clear cached queries related to these project cohorts and queue
        # a task to re-cached them.
        to_delete = []
        if self.organization_id:
            to_delete.append(util.cached_query_key(
                'SuperDashboard', organization_id=self.organization_id
            ))
        for pc in pcs:
            kwargs = {'program_label': pc.program_label,
                      'cohort_label': pc.cohort_label}
            to_delete.append(util.cached_query_key('SuperDashboard', **kwargs))
            taskqueue.add(
                url='/task/cache_dashboard',
                headers={'Content-Type': 'application/json; charset=utf-8'},
                payload=json.dumps(kwargs),
                countdown=config.task_consistency_countdown,
            )
        memcache.delete_multi(to_delete)
Ejemplo n.º 8
0
    def test_put_clears_dashboard_queries(self):
        org, project, pc, checkpoint = self.create_with_project_cohort()

        org_key = util.cached_query_key(
            'SuperDashboard',
            organization_id=pc.organization_id,
        )
        program_cohort_key = util.cached_query_key(
            'SuperDashboard',
            program_label=pc.program_label,
            cohort_label=pc.cohort_label,
        )

        memcache.set(org_key, {'foo': 1})
        memcache.set(program_cohort_key, {'foo': 1})

        # This should clear memcache.
        checkpoint.status = 'complete'
        checkpoint.put()

        self.assertIsNone(memcache.get(org_key))
        self.assertIsNone(memcache.get(program_cohort_key))