From 49dc0053cebe24e482b5169a50a97eeeb685a40a Mon Sep 17 00:00:00 2001 From: Shayan Shiravani Date: Sun, 17 Sep 2023 13:39:34 +0330 Subject: [PATCH 1/2] Prizetap: drawing the raffle automatically --- brightIDfaucet/celery.py | 4 ++++ core/helpers.py | 20 ++++++++++++++++++++ prizetap/tasks.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 core/helpers.py create mode 100644 prizetap/tasks.py diff --git a/brightIDfaucet/celery.py b/brightIDfaucet/celery.py index c5f9c812..19ce2d2e 100644 --- a/brightIDfaucet/celery.py +++ b/brightIDfaucet/celery.py @@ -45,6 +45,10 @@ 'update-donation-receipt-status': { "task": "faucet.tasks.update_donation_receipt_pending_status", "schedule": 60, + }, + "draw-prizetap-raffles": { + "task": "prizetap.tasks.draw_the_expired_raffles", + "schedule": 60 } } diff --git a/core/helpers.py b/core/helpers.py new file mode 100644 index 00000000..492ce996 --- /dev/null +++ b/core/helpers.py @@ -0,0 +1,20 @@ +import time +from contextlib import contextmanager +from django.core.cache import cache + +@contextmanager +def memcache_lock(lock_id, oid, lock_expire=60): + timeout_at = time.monotonic() + lock_expire + # cache.add fails if the key already exists + status = cache.add(lock_id, oid, lock_expire) + try: + yield status + finally: + # memcache delete is very slow, but we have to use it to take + # advantage of using add() for atomic locking + if time.monotonic() < timeout_at and status: + # don't release the lock if we exceeded the timeout + # to lessen the chance of releasing an expired lock + # owned by someone else + # also don't release the lock if we didn't acquire it + cache.delete(lock_id) \ No newline at end of file diff --git a/prizetap/tasks.py b/prizetap/tasks.py new file mode 100644 index 00000000..475875ed --- /dev/null +++ b/prizetap/tasks.py @@ -0,0 +1,30 @@ +from celery import shared_task +from django.utils import timezone +from core.helpers import memcache_lock +from .models import Raffle +from .utils import PrizetapContractClient + + +@shared_task(bind=True) +def draw_the_expired_raffles(self): + + id = f"{self.name}-LOCK" + + with memcache_lock(id, self.app.oid) as acquired: + if not acquired: + print(f"Could not acquire process lock at {self.name}") + return + + raffles_queryset = ( + Raffle.objects + .filter(deadline__lt=timezone.now()) + .filter(is_active=True) + ) + if raffles_queryset.count() > 0: + for raffle in raffles_queryset: + if raffle.number_of_onchain_entries > 0 and not raffle.winner_entry: + print(f"Drawing the raffle {raffle.name}") + raffle_client = PrizetapContractClient(raffle) + if raffle_client.draw_raffle(): + raffle.is_active = False + raffle.save() From 543393a37327dfa890b5f48a4e4d257e48f6da13 Mon Sep 17 00:00:00 2001 From: Mohamad Bastin Date: Mon, 18 Sep 2023 13:14:30 +0200 Subject: [PATCH 2/2] add age to raffle entry admin --- prizetap/admin.py | 3 ++- prizetap/models.py | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/prizetap/admin.py b/prizetap/admin.py index ec2ead7b..70c97e2a 100644 --- a/prizetap/admin.py +++ b/prizetap/admin.py @@ -10,7 +10,8 @@ class RaffleŁEntryAdmin(admin.ModelAdmin): list_display = [ "pk", "raffle", - "get_wallet" + "get_wallet", + "age", ] @admin.display(ordering='user_profile__wallets', description='Wallet') diff --git a/prizetap/models.py b/prizetap/models.py index 512bc572..30460993 100644 --- a/prizetap/models.py +++ b/prizetap/models.py @@ -126,6 +126,10 @@ def __str__(self): def user(self): return self.user_profile.wallets.get(wallet_type=NetworkTypes.EVM).address + @property + def age(self): + return timezone.now() - self.created_at + def save(self, *args, **kwargs): if self.is_winner: try: