Open Fundi1330 opened 1 month ago
Same problem here. This is a huge blocker.
Another problem that practically always occurs is that when starting the beat instance, there's a 'warmup' (usually 5-20 minutes) in which no scheduled tasks are run; they're just skipped.
This combined with the other issue makes it impossible to run this in production unfortunately.
I don't have the second problem
Has someone been able to solve this?
Here is what I want to do. When the user clicks on a button it sends a post request via Ajax to /api/start_mining endpoint, which creates a task to mine points. Every 5 seconds it triggers the task to mine 1000 points and after 25 seconds the task deletes itself and the user can now claim points and start the whole process again. The problem is that after Ajax sends a post request celery redbeat starts the first task after a certain cooldown or sometimes doesn't start it. Because of this, the user does not get points or get not enough
Here are my API routes: ` @api_bp.route('/start_mining', methods=['POST']) def start_mining(): now = datetime.utcnow() user = get_current_user() user.last_date_points_claimed = datetime.now() db.session.commit()
@api_bp.route('/claim_coins', methods=['POST']) def claim_coins(): user = get_current_user() user.points += user.mined_points user.mined_points = 0 db.session.commit()
@api_bp.route('/mined', methods=['POST']) @csrf.exempt def mined(): data = request.json user: User = User.query.get_or_404(data['id']) emit('mine', {'points': user.mined_points}, namespace='/', json=True, broadcast=True)
@api_bp.route('/end_mining', methods=['POST']) @csrf.exempt def end_mining(): data = request.json user = User.query.get(data['id']) emit('end_mining', {'new_button': render_template('includes/mining_button.html', user=user)}, namespace='/', json=True, broadcast=True)
My celery file and task
from celery import Celery, Task from celery import current_app as celery_app from flask import Flask, current_app from .models import User from datetime import datetime, timedelta from os import environ from redbeat import RedBeatSchedulerEntry from .config import db from requests import sessiondef celery_init_app(app: Flask): class SportyTask(Task): def call(self, *args, *kwargs): with app.app_context(): return self.run(args, **kwargs)
@celery_app.task(ignore_result=False) def mine_points(user_id: int, mined_url: str, end_mining_url: str, schedule_name: str): user: User = User.query.get(user_id) difference: timedelta = datetime.now() - user.last_date_points_claimed
`
Celery config:
CELERY = { 'broker_url': 'redis://localhost:6379/0', 'result_backend': 'redis://localhost:6379/0', 'task_ignore_result': True, 'beat_scheduler': 'redbeat.RedBeatScheduler', 'broker_transport_options': { 'max_retries': 3, 'interval_start': 0, 'interval_step': 0.2, 'interval_max': 0.2, } }
P.S. Redis runs on the WSL server and Celery connects to it successfully. I run my flask app on windows