Skip to content

Commit

Permalink
Prizetap: drawing the raffle automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
ShayanShiravani committed Sep 17, 2023
1 parent ed858a7 commit 49dc005
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
4 changes: 4 additions & 0 deletions brightIDfaucet/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
20 changes: 20 additions & 0 deletions core/helpers.py
Original file line number Diff line number Diff line change
@@ -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)
30 changes: 30 additions & 0 deletions prizetap/tasks.py
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit 49dc005

Please sign in to comment.