Browse Source

Phase 4: extend AnonCachePageMixin to materia and sessao public detail views

MateriaLegislativaCrud.DetailView and SessaoCrud.DetailView are the two
highest-traffic public views not yet covered by anonymous page caching.
Both are read-only for anonymous visitors, making them safe cache targets.

- MateriaLegislativaCrud.DetailView: 300s TTL (PAGE_CACHE_TTL_DETAIL)
- SessaoCrud.DetailView: 120s TTL (PAGE_CACHE_TTL_LIST — sessions update
  more frequently during active legislative sittings)

NormaCrud.DetailView intentionally left uncached: it writes NormaEstatisticas
on every access, and caching would suppress per-visit statistics for anonymous
users.

Also includes the RATELIMIT_DRY_RUN=False docker-compose.yaml change
from the previous session (rate limiting now enforced in docker-compose).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rate-limiter-2026
Edward Ribeiro 3 weeks ago
parent
commit
1940c2fd10
  1. 1
      docker/docker-compose.yaml
  2. 7
      sapl/materia/views.py
  3. 8
      sapl/sessao/views.py

1
docker/docker-compose.yaml

@ -88,6 +88,7 @@ services:
TZ: America/Sao_Paulo TZ: America/Sao_Paulo
REDIS_URL: redis://saplredis:6379 REDIS_URL: redis://saplredis:6379
CACHE_BACKEND: redis CACHE_BACKEND: redis
RATELIMIT_DRY_RUN: 'False'
volumes: volumes:
- sapl_data:/var/interlegis/sapl/data - sapl_data:/var/interlegis/sapl/data
- sapl_media:/var/interlegis/sapl/media - sapl_media:/var/interlegis/sapl/media

7
sapl/materia/views.py

@ -59,6 +59,7 @@ from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo, get_base_u
show_results_filter_set, get_tempfile_dir, show_results_filter_set, get_tempfile_dir,
google_recaptcha_configured, MultiFormatOutputMixin) google_recaptcha_configured, MultiFormatOutputMixin)
from sapl.middleware.ratelimit import get_client_ip, smart_key, smart_rate from sapl.middleware.ratelimit import get_client_ip, smart_key, smart_rate
from sapl.middleware.page_cache import AnonCachePageMixin
from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
AnexadaEmLoteFilterSet, AdicionarVariasAutoriasFilterSet, AnexadaEmLoteFilterSet, AdicionarVariasAutoriasFilterSet,
@ -1882,7 +1883,11 @@ class MateriaLegislativaCrud(Crud):
def get_success_url(self): def get_success_url(self):
return self.search_url return self.search_url
class DetailView(Crud.DetailView): class DetailView(AnonCachePageMixin, Crud.DetailView):
# Materia detail pages are public, read-only, and change infrequently
# once published. Cache anonymous responses for 5 minutes to absorb
# bot and search-engine traffic without hitting PostgreSQL.
anon_cache_ttl = 300 # PAGE_CACHE_TTL_DETAIL
layout_key = 'MateriaLegislativaDetail' layout_key = 'MateriaLegislativaDetail'
template_name = "materia/materialegislativa_detail.html" template_name = "materia/materialegislativa_detail.html"

8
sapl/sessao/views.py

@ -49,6 +49,7 @@ from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm, OrdemExpedien
from sapl.sessao.models import Correspondencia from sapl.sessao.models import Correspondencia
from sapl.settings import TIME_ZONE from sapl.settings import TIME_ZONE
from sapl.middleware.ratelimit import get_client_ip, smart_key, smart_rate from sapl.middleware.ratelimit import get_client_ip, smart_key, smart_rate
from sapl.middleware.page_cache import AnonCachePageMixin
from sapl.utils import show_results_filter_set, remover_acentos, \ from sapl.utils import show_results_filter_set, remover_acentos, \
MultiFormatOutputMixin, PautaMultiFormatOutputMixin MultiFormatOutputMixin, PautaMultiFormatOutputMixin
@ -1347,7 +1348,12 @@ class SessaoCrud(Crud):
{'subnav_template_name': 'sessao/subnav-solene.yaml'}) {'subnav_template_name': 'sessao/subnav-solene.yaml'})
return context return context
class DetailView(Crud.DetailView): class DetailView(AnonCachePageMixin, Crud.DetailView):
# Session plenary detail pages are public and read-only during the
# session. Cache anonymous responses for 2 minutes — short enough
# that real-time voting tallies visible in the detail page stay
# reasonably fresh for public observers.
anon_cache_ttl = 120 # PAGE_CACHE_TTL_LIST
@property @property
def layout_key(self): def layout_key(self):

Loading…
Cancel
Save