| Conditions | 9 |
| Total Lines | 29 |
| Code Lines | 26 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
| 1 | # -*- coding: utf-8 -*- |
||
| 26 | def retriable(count=3, sync=False, reraise=True, on_retry_exhausted=None): |
||
| 27 | """Retries DB commits |
||
| 28 | """ |
||
| 29 | |||
| 30 | def decorator(func): |
||
| 31 | def wrapped(*args, **kwargs): |
||
| 32 | retried = 0 |
||
| 33 | if sync: |
||
| 34 | try: |
||
| 35 | api.get_portal()._p_jar.sync() |
||
| 36 | except Exception: |
||
| 37 | pass |
||
| 38 | while retried < count: |
||
| 39 | try: |
||
| 40 | return func(*args, **kwargs) |
||
| 41 | except ConflictError: |
||
| 42 | retried += 1 |
||
| 43 | logger.warn("DB ConflictError: Retrying %s/%s" |
||
| 44 | % (retried, count)) |
||
| 45 | try: |
||
| 46 | api.get_portal()._p_jar.sync() |
||
| 47 | except Exception: |
||
| 48 | if retried >= count: |
||
| 49 | if on_retry_exhausted is not None: |
||
| 50 | on_retry_exhausted(*args, **kwargs) |
||
| 51 | if reraise: |
||
| 52 | raise |
||
| 53 | return wrapped |
||
| 54 | return decorator |
||
| 55 |