2021-07-20 11:00:49 -03:00
|
|
|
import logging
|
2021-12-21 16:32:30 -03:00
|
|
|
import time
|
2021-07-20 11:00:49 -03:00
|
|
|
|
|
|
|
from flask import Flask
|
2021-12-21 16:31:41 -03:00
|
|
|
import redis
|
2021-07-20 11:00:49 -03:00
|
|
|
|
|
|
|
import constants
|
|
|
|
import invoice_helpers
|
|
|
|
import order_helpers
|
2021-12-21 16:31:41 -03:00
|
|
|
import transmitter
|
2021-07-20 11:00:49 -03:00
|
|
|
from database import db
|
2021-12-21 16:32:30 -03:00
|
|
|
from models import TxRetry
|
2021-07-20 11:00:49 -03:00
|
|
|
from worker import Worker
|
|
|
|
|
|
|
|
ONE_MINUTE = 60
|
|
|
|
CLEANUP_DUTY_CYCLE = 5 * ONE_MINUTE # five minutes
|
2021-12-21 16:32:30 -03:00
|
|
|
ORDER_RETRANSMIT_CYCLE_SECONDS = 10
|
2021-07-20 11:00:49 -03:00
|
|
|
|
|
|
|
|
|
|
|
def cleanup_database(app):
|
|
|
|
with app.app_context():
|
|
|
|
(expired_invoices,
|
|
|
|
expired_orders) = invoice_helpers.expire_unpaid_invoices()
|
|
|
|
expired_orders.extend(order_helpers.expire_old_pending_orders())
|
|
|
|
cleaned_up_orders = order_helpers.cleanup_old_message_files()
|
|
|
|
|
|
|
|
work = [
|
|
|
|
len(x)
|
|
|
|
for x in [expired_invoices, expired_orders, cleaned_up_orders]
|
|
|
|
]
|
|
|
|
if (any(work)):
|
|
|
|
logging.info("Database cleanup: expired {} invoices, "
|
|
|
|
"{} orders, and removed {} files".format(*work))
|
|
|
|
|
|
|
|
|
2021-12-21 16:32:30 -03:00
|
|
|
def retry_transmission(app):
|
|
|
|
with app.app_context():
|
|
|
|
order_helpers.refresh_retransmission_table()
|
|
|
|
any_retry_record = TxRetry.query.first()
|
|
|
|
if any_retry_record:
|
|
|
|
transmitter.tx_start()
|
|
|
|
|
|
|
|
|
2021-12-21 16:31:41 -03:00
|
|
|
def start_workers(app):
|
|
|
|
cleanup_worker = Worker(period=CLEANUP_DUTY_CYCLE,
|
|
|
|
fcn=cleanup_database,
|
|
|
|
args=(app, ),
|
|
|
|
name="database cleaner")
|
|
|
|
|
2021-12-21 16:32:30 -03:00
|
|
|
retry_worker = Worker(period=ORDER_RETRANSMIT_CYCLE_SECONDS,
|
|
|
|
fcn=retry_transmission,
|
|
|
|
args=(app, ),
|
|
|
|
name="order retransmission")
|
|
|
|
|
2021-12-21 16:31:41 -03:00
|
|
|
cleanup_worker.thread.join()
|
2021-12-21 16:32:30 -03:00
|
|
|
retry_worker.thread.join()
|
2021-12-21 16:31:41 -03:00
|
|
|
|
|
|
|
|
2021-07-20 11:00:49 -03:00
|
|
|
def create_app():
|
|
|
|
app = Flask(__name__)
|
|
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{constants.DB_FILE}'
|
|
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
2021-12-21 16:31:41 -03:00
|
|
|
app.config["REDIS_INSTANCE"] = redis.from_url(constants.REDIS_URI)
|
2021-07-20 11:00:49 -03:00
|
|
|
db.init_app(app)
|
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
logging.basicConfig(level=logging.DEBUG, format=constants.LOGGING_FORMAT)
|
|
|
|
app = create_app()
|
|
|
|
|
|
|
|
with app.app_context():
|
2021-12-21 16:31:41 -03:00
|
|
|
db.create_all()
|
2021-12-21 16:32:30 -03:00
|
|
|
# To avoid calling tx_start on each gunicorn worker, call it here once
|
|
|
|
# instead. Also, wait a bit before calling tx_start so that clients
|
|
|
|
# have enough time to reconnect to the SSE server.
|
|
|
|
time.sleep(3)
|
2021-12-21 16:31:41 -03:00
|
|
|
transmitter.tx_start()
|
|
|
|
start_workers(app)
|
2021-07-20 11:00:49 -03:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|