Heroku caching api responses [django/restframework]
Heroku caching api responses [django/restframework]
Heroku seams to be caching api responses from my Django/RestFramework app. I have no caching mechanism enabled on restframework.
Looking at the logs, I can see a error response (400) caused by a object not found, and, right before, the python stacktrace. Then I populate the object table and here happens the issue. On next requests, que error doesn't happen anymore, but the response is exactly the same 400 as before!
Eventually, I get alternate 200/400 responses.
Edit 1: When I get 400 response, it's not just the code, but also the body. My code throws no error, but the response is code 400 and the first error message.
Edit 2: Added bellow my view and my serializer, with not relevant parts ommited
The log with error:
2018-06-29T11:34:45.991094+00:00 app[web.1]: INFO 2018-06-29 08:34:45,990 dados: 1 [1/1] 6.34 Kb AGUARDANDO: importação síncrona iniciada
2018-06-29T11:34:46.044547+00:00 app[web.1]: UF Destino AC
2018-06-29T11:34:46.048998+00:00 app[web.1]: ERROR 2018-06-29 08:34:46,046 importacao_erp: Arquivo "1 [1/1] 6.34 Kb PROCESSANDO": icms[0]: objeto referenciado não existe (Uf matching query does not exist.)
2018-06-29T11:34:46.049002+00:00 app[web.1]: Traceback (most recent call last):
2018-06-29T11:34:46.049004+00:00 app[web.1]: File "/app/core/importacao_erp.py", line 123, in importacao
2018-06-29T11:34:46.049006+00:00 app[web.1]: method_save(dict(dados))
2018-06-29T11:34:46.049008+00:00 app[web.1]: File "/app/core/importacao_erp.py", line 282, in save_icms
2018-06-29T11:34:46.049009+00:00 app[web.1]: uf_destino=Uf.objects.get(sigla=dados['uf_destino']),
2018-06-29T11:34:46.049011+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
2018-06-29T11:34:46.049013+00:00 app[web.1]: return getattr(self.get_queryset(), name)(*args, **kwargs)
2018-06-29T11:34:46.049015+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/query.py", line 403, in get
2018-06-29T11:34:46.049016+00:00 app[web.1]: self.model._meta.object_name
2018-06-29T11:34:46.049022+00:00 app[web.1]: core.models.uf.DoesNotExist: Uf matching query does not exist.
2018-06-29T11:34:46.311674+00:00 app[web.1]: ERROR 2018-06-29 08:34:46,311 importacao_erp: Arquivo "1 [1/1] 6.34 Kb PROCESSANDO": clientes[0]: objeto referenciado não existe (Uf matching query does not exist.)
2018-06-29T11:34:46.311687+00:00 app[web.1]: Traceback (most recent call last):
2018-06-29T11:34:46.311690+00:00 app[web.1]: File "/app/core/importacao_erp.py", line 123, in importacao
2018-06-29T11:34:46.311693+00:00 app[web.1]: method_save(dict(dados))
2018-06-29T11:34:46.311695+00:00 app[web.1]: File "/app/core/importacao_erp.py", line 393, in save_clientes
2018-06-29T11:34:46.311696+00:00 app[web.1]: endereco['uf'] = Uf.objects.get(sigla=endereco['uf'])
2018-06-29T11:34:46.311698+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
2018-06-29T11:34:46.311700+00:00 app[web.1]: return getattr(self.get_queryset(), name)(*args, **kwargs)
2018-06-29T11:34:46.311702+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/query.py", line 403, in get
2018-06-29T11:34:46.311704+00:00 app[web.1]: self.model._meta.object_name
2018-06-29T11:34:46.311711+00:00 app[web.1]: core.models.uf.DoesNotExist: Uf matching query does not exist.
2018-06-29T11:34:46.412053+00:00 app[web.1]: 10.123.227.73 - - [29/Jun/2018:08:34:46 -0300] "POST /api/erp/dados/ HTTP/1.1" 400 548 "-" "insomnia/5.16.2"
2018-06-29T11:34:46.412316+00:00 heroku[router]: at=info method=POST path="/api/erp/dados/" host=solumobi-gweb.herokuapp.com request_id=99ef2ab0-a6a5-4a3a-a767-157d9acfc355 fwd="177.156.123.248" dyno=web.1 connect=1ms service=447ms status=400 bytes=794 protocol=https
And then, without error, but still 400:
2018-06-29T11:35:31.299633+00:00 app[web.1]: INFO 2018-06-29 08:35:31,299 dados: 3 [1/1] 6.34 Kb AGUARDANDO: importação síncrona iniciada
2018-06-29T11:35:31.342317+00:00 app[web.1]: UF Destino AC
2018-06-29T11:35:31.721914+00:00 heroku[router]: at=info method=POST path="/api/erp/dados/" host=solumobi-gweb.herokuapp.com request_id=55e90b74-4c37-42ef-872b-66a8f64bb9cc fwd="177.156.123.248" dyno=web.1 connect=0ms service=437ms status=400 bytes=794 protocol=https
2018-06-29T11:35:31.721356+00:00 app[web.1]: 10.123.227.73 - - [29/Jun/2018:08:35:31 -0300] "POST /api/erp/dados/ HTTP/1.1" 400 548 "-" "insomnia/5.16.2"
2018-06-29T11:35:40.270332+00:00 app[web.1]: INFO 2018-06-29 08:35:40,270 dados: 4 [1/1] 6.34 Kb AGUARDANDO: importação síncrona iniciada
2018-06-29T11:35:40.328652+00:00 app[web.1]: UF Destino AC
2018-06-29T11:35:40.960751+00:00 heroku[router]: at=info method=POST path="/api/erp/dados/" host=solumobi-gweb.herokuapp.com request_id=cb358bca-3301-4c1e-8468-6387ae7aaaea fwd="177.156.123.248" dyno=web.1 connect=0ms service=726ms status=400 bytes=794 protocol=https
2018-06-29T11:35:40.960283+00:00 app[web.1]: 10.123.227.73 - - [29/Jun/2018:08:35:40 -0300] "POST /api/erp/dados/ HTTP/1.1" 400 548 "-" "insomnia/5.16.2"
2018-06-29T11:35:48.349108+00:00 app[web.1]: INFO 2018-06-29 08:35:48,348 dados: 5 [1/1] 6.34 Kb AGUARDANDO: importação síncrona iniciada
2018-06-29T11:35:48.418827+00:00 app[web.1]: UF Destino AC
2018-06-29T11:35:48.869927+00:00 heroku[router]: at=info method=POST path="/api/erp/dados/" host=solumobi-gweb.herokuapp.com request_id=9a5e8746-57b2-4e89-b5d6-8f40a89d1eee fwd="177.156.123.248" dyno=web.1 connect=0ms service=541ms status=400 bytes=794 protocol=https
View Code, with not relevant parts ommited:
router.register('dados', DadosViewSet, base_name="api-erp-dados")
class DadosViewSet(viewsets.ViewSet):
def create(self, request):
arquivo = ArquivoImportacao()
arquivo.dados = dados
arquivo.save()
ImportadorERP(arquivo).importar()
status = 201 if arquivo.status == STATUS_IMPORTADO else 400
s = ArquivoImportacaoSerializer(arquivo)
return Response(s.data, status)
class ArquivoImportacaoSerializer(serializers.ModelSerializer):
log = ArquivoImportacaoLogSerializer(source="arquivoimportacaolog_set", many=True, read_only=True)
tamanho = serializers.CharField(source="tamanho_fmt", read_only=True)
class Meta:
model = ArquivoImportacao
fields = ['codigo', 'data', 'tamanho', 'status', 'log']
You should show the code of that view.
– Daniel Roseman
Jun 29 at 12:22
Look at the "UF Destino AC" log entries. At that point, my code is trying to fetch objects fom Uf model. At the first time, the model is empty, so an error is thrown. At the second time and so on, I had populated the modal, so no error is thrown and the process gets done correctly. But, for some reason, the response is the same. I just can think of response caching. One thing I forgot to mention is that not just response code was the same, but also the body (I'll edit the question). There's also the fact that sometimes the response alternates between the first error and the correct one.
– Paulo Brito
Jun 29 at 18:06
@Damien, what about gunicorn or nginx? Do they do response caching?
– Paulo Brito
Jun 30 at 11:48
1 Answer
1
I figured out. The class ImportadorERP above had it's log list declared at wrong place, so it became static, holding logs from several requests of it process.
Sorry for wasting your time. Thanks for you help.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
No, heroku isn't caching your requests. The best way to better understand what's happening here would be to reproduce the error and look at what content your app returns.
– Damien MATHIEU
Jun 29 at 12:15