Skip to content

Commit f4b2bdb

Browse files
author
Eric Harmeling
authored
Updated view retry function control flow, error exceptions (#123)
* Updated view retry function control flow, error exceptions * Fix retry decorator calls
1 parent c8ba206 commit f4b2bdb

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

python/django/cockroach_example/views.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,34 @@
22
from django.utils.decorators import method_decorator
33
from django.views.generic import View
44
from django.views.decorators.csrf import csrf_exempt
5-
from django.db import Error, IntegrityError
5+
from django.db import Error, OperationalError
66
from django.db.transaction import atomic
7-
7+
from psycopg2 import errorcodes
8+
from functools import wraps
89
import json
910
import sys
1011
import time
1112

1213
from .models import *
1314

1415
# Warning: Do not use retry_on_exception in an inner nested transaction.
15-
def retry_on_exception(num_retries=3, on_failure=HttpResponse(status=500), delay_=0.5, backoff_=1.5):
16-
def retry(view):
17-
def wrapper(*args, **kwargs):
18-
delay = delay_
19-
for i in range(num_retries):
20-
try:
21-
return view(*args, **kwargs)
22-
except IntegrityError as ex:
23-
if i == num_retries - 1:
24-
return on_failure
25-
elif getattr(ex.__cause__, 'pgcode', '') == errorcodes.SERIALIZATION_FAILURE:
26-
time.sleep(delay)
27-
delay *= backoff_
28-
except Error as ex:
16+
def retry_on_exception(view, num_retries=3, on_failure=HttpResponse(status=500), delay_=0.5, backoff_=1.5):
17+
@wraps(view)
18+
def retry(*args, **kwargs):
19+
delay = delay_
20+
for i in range(num_retries):
21+
try:
22+
return view(*args, **kwargs)
23+
except OperationalError as ex:
24+
if i == num_retries - 1:
25+
return on_failure
26+
elif getattr(ex.__cause__, 'pgcode', '') == errorcodes.SERIALIZATION_FAILURE:
27+
time.sleep(delay)
28+
delay *= backoff_
29+
else:
2930
return on_failure
30-
return wrapper
31+
except Error as ex:
32+
return on_failure
3133
return retry
3234

3335
class PingView(View):
@@ -43,7 +45,7 @@ def get(self, request, id=None, *args, **kwargs):
4345
customers = list(Customers.objects.filter(id=id).values())
4446
return JsonResponse(customers, safe=False)
4547

46-
@retry_on_exception(3)
48+
@retry_on_exception
4749
@atomic
4850
def post(self, request, *args, **kwargs):
4951
form_data = json.loads(request.body.decode())
@@ -52,7 +54,7 @@ def post(self, request, *args, **kwargs):
5254
c.save()
5355
return HttpResponse(status=200)
5456

55-
@retry_on_exception(3)
57+
@retry_on_exception
5658
@atomic
5759
def delete(self, request, id=None, *args, **kwargs):
5860
if id is None:
@@ -72,7 +74,7 @@ def get(self, request, id=None, *args, **kwargs):
7274
products = list(Products.objects.filter(id=id).values())
7375
return JsonResponse(products, safe=False)
7476

75-
@retry_on_exception(3)
77+
@retry_on_exception
7678
@atomic
7779
def post(self, request, *args, **kwargs):
7880
form_data = json.loads(request.body.decode())
@@ -93,7 +95,7 @@ def get(self, request, id=None, *args, **kwargs):
9395
orders = list(Orders.objects.filter(id=id).values())
9496
return JsonResponse(orders, safe=False)
9597

96-
@retry_on_exception(3)
98+
@retry_on_exception
9799
@atomic
98100
def post(self, request, *args, **kwargs):
99101
form_data = json.loads(request.body.decode())

0 commit comments

Comments
 (0)