Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scheduled job to change status to expired #1116

Merged
merged 18 commits into from
Apr 4, 2022
98 changes: 85 additions & 13 deletions dds_web/scheduled_tasks.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,96 @@
import flask_apscheduler
import flask

# Apscheduler
## Apscheduler
scheduler = flask_apscheduler.APScheduler()


@scheduler.task("interval", id="available_to_expired", seconds=10, misfire_grace_time=1)
def change_status_to_expired():
# print("Task: Change project status from Available to expired.", flush=True)
from dds_web.database import models
@scheduler.task("cron", id="available_to_expired", hour=0, minute=1, misfire_grace_time=3600)
# @scheduler.task("interval", id="available_to_expired", seconds=15, misfire_grace_time=1)
def set_available_to_expired():
scheduler.app.logger.debug("Task: Checking for Expiring projects.")
import sqlalchemy

# from dds_web.utils import current_time, page_query
from dds_web import db
from dds_web.database import models
from dds_web.errors import DatabaseError
from dds_web.api.project import ProjectStatus
from dds_web.utils import current_time, page_query

with scheduler.app.app_context():
# scheduler.app.logger.debug("This means that the app context works!")
test = models.Project.query.all()
# print(test, flush=True)
expire = ProjectStatus()

errors = {}

try:
for unit in db.session.query(models.Unit).with_for_update().all():
errors[unit.name] = {}

days_in_expired = unit.days_in_expired

for project in page_query(
db.session.query(models.Project)
.filter(
sqlalchemy.and_(
models.Project.is_active == 1, models.Project.unit_id == unit.id
)
)
.with_for_update()
):

if (
project.current_status == "Available"
and project.current_deadline <= current_time()
):
scheduler.app.logger.debug("Handling expiring project")
scheduler.app.logger.debug(
"Project: %s has status %s and expires on: %s",
project.id,
project.current_status,
project.current_deadline,
)
new_status_row = expire.expire_project(
project=project,
current_time=current_time(),
deadline_in=days_in_expired,
)

project.project_statuses.append(new_status_row)

# for project in page_query(
# models.ProjectStatuses.query.filter(models.ProjectStatuses.deadline <= current_time())
# ):
try:
db.session.commit()
scheduler.app.logger.debug(
"Project: %s has status Archived now!", project.public_id
)
except (
sqlalchemy.exc.OperationalError,
sqlalchemy.exc.SQLAlchemyError,
) as err:
flask.current_app.logger.exception(err)
db.session.rollback()
errors[unit.name][project.public_id] = str(err)
continue
else:
scheduler.app.logger.debug(
"Nothing to do for Project: %s", project.public_id
)
except (sqlalchemy.exc.OperationalError, sqlalchemy.exc.SQLAlchemyError) as err:
flask.current_app.logger.exception(err)
db.session.rollback()
raise DatabaseError(
message=str(err),
alt_message=f"Status update failed"
+ (
": Database malfunction."
if isinstance(err, sqlalchemy.exc.OperationalError)
else "."
),
) from err

# flask.current_app.logger.debug("Project: %s - Expires: %s", project, project.expires)
for unit, projects in errors.items():
if projects:
scheduler.app.logger.error(
f"Following projects of Unit '{unit}' encountered issues during expiration process:"
)
for proj in errors[unit].keys():
scheduler.app.logger.error(f"Error for project '{proj}': {errors[unit][proj]} ")