def funnel(self, request: request.Request, *args: Any, **kwargs: Any) -> Response: team = self.team refresh = should_refresh(request) dashboard_id = request.GET.get("from_dashboard", None) filter = Filter(request=request) cache_key = generate_cache_key("{}_{}".format(filter.toJSON(), team.pk)) result = {"loading": True} if refresh: cache.delete(cache_key) else: cached_result = get_safe_cache(cache_key) if cached_result: task_id = cached_result.get("task_id", None) if not task_id: return Response(cached_result["result"]) else: return Response(result) payload = {"filter": filter.toJSON(), "team_id": team.pk} task = update_cache_item_task.delay(cache_key, CacheType.FUNNEL, payload) if not task.ready(): task_id = task.id cache.set(cache_key, {"task_id": task_id}, 180) # task will be live for 3 minutes if dashboard_id: DashboardItem.objects.filter(pk=dashboard_id).update( last_refresh=now()) return Response(result)
def calculate_funnel(self, request: request.Request) -> Dict[str, Any]: team = self.team refresh = should_refresh(request) filter = Filter(request=request, data={ **request.data, "insight": INSIGHT_FUNNELS }) cache_key = generate_cache_key("{}_{}".format(filter.toJSON(), team.pk)) result = {"loading": True} if refresh: cache.delete(cache_key) else: cached_result = get_safe_cache(cache_key) if cached_result: task_id = cached_result.get("task_id", None) if not task_id: return {"result": cached_result["result"]} else: return {"result": result} payload = {"filter": filter.toJSON(), "team_id": team.pk} task = update_cache_item_task.delay(cache_key, CacheType.FUNNEL, payload) if not task.ready(): task_id = task.id cache.set(cache_key, {"task_id": task_id}, 180) # task will be live for 3 minutes self._refresh_dashboard(request=request) return {"result": result}
def wrapper(self, request) -> T: # prepare caching params team = cast(User, request.user).team if not team: return f(self, request) filter = get_filter(request=request, team=team) cache_key = generate_cache_key("{}_{}".format(filter.toJSON(), team.pk)) # return cached result if possible if not should_refresh(request): cached_result_package = get_safe_cache(cache_key) if cached_result_package and cached_result_package.get("result"): cached_result_package["is_cached"] = True return cached_result_package # call function being wrapped fresh_result_package = cast(T, f(self, request)) # cache new data if isinstance(fresh_result_package, dict): result = fresh_result_package.get("result") if not isinstance(result, dict) or not result.get("loading"): fresh_result_package["last_refresh"] = now() fresh_result_package["is_cached"] = False cache.set( cache_key, fresh_result_package, TEMP_CACHE_RESULTS_TTL, ) if filter: dashboard_items = Insight.objects.filter( team_id=team.pk, filters_hash=cache_key) dashboard_items.update(last_refresh=now()) return fresh_result_package
def get_result(self, insight: Insight): if not insight.filters: return None if should_refresh(self.context["request"]): return update_dashboard_item_cache(insight, None) result = get_safe_cache(insight.filters_hash) if not result or result.get("task_id", None): return None # Data might not be defined if there is still cached results from before moving from 'results' to 'data' return result.get("result")
def get_last_refresh(self, insight: Insight): if should_refresh(self.context["request"]): return now() result = self.get_result(insight) if result is not None: return insight.last_refresh if insight.last_refresh is not None: # Update last_refresh without updating "updated_at" (insight edit date) insight.last_refresh = None insight.save() return None
def wrapper(*args, **kwargs) -> Dict[str, Union[List, datetime, bool, str]]: # prepare caching params request: Request = args[1] team = cast(User, request.user).team filter = None if not team: return f(*args, **kwargs) filter = get_filter(request=request, team=team) cache_key = generate_cache_key("{}_{}".format( filter.toJSON(), team.pk)) # return cached result if possible if not should_refresh(request): cached_result = get_safe_cache(cache_key) if cached_result and cached_result.get("result"): return {**cached_result, "is_cached": True} # call function being wrapped result = f(*args, **kwargs) # cache new data if result is not None and not ( isinstance(result.get("result"), dict) and result["result"].get("loading")): cache.set( cache_key, { "result": result["result"], "last_refresh": now() }, TEMP_CACHE_RESULTS_TTL, ) if filter: dashboard_items = DashboardItem.objects.filter( team_id=team.pk, filters_hash=cache_key) dashboard_items.update(last_refresh=now()) return result
def test_should_not_refresh_with_data_false(self): drf_request = Request(HttpRequest()) drf_request._full_data = {"refresh": False} # type: ignore self.assertFalse(should_refresh(drf_request))
def test_should_refresh_with_data_true(self): drf_request = Request(HttpRequest()) drf_request._full_data = {"refresh": True} # type: ignore self.assertTrue(should_refresh((drf_request)))
def test_should_not_refresh_with_refresh_gibberish(self): request = HttpRequest() request.GET["refresh"] = "2132klkl" self.assertFalse(should_refresh(Request(request)))
def test_should_not_refresh_with_refresh_false(self): request = HttpRequest() request.GET["refresh"] = "false" self.assertFalse(should_refresh(Request(request)))
def test_should_refresh_with_refresh_empty(self): request = HttpRequest() request.GET["refresh"] = "" self.assertTrue(should_refresh(Request(request)))