Async Fonksiyonlarla Cron Oluşturma

Selamlar. Bir problemim var. Flask üzerinde api rotalarını oluşturup app.run() ile projeyi ayağa kaldırıyorum. Bunu yanında cron’larım var. Örnek cron yapım:

from apscheduler.schedulers.asyncio import AsyncIOScheduler
import asyncio

async def deneme():
    await islemler()    

def startCron():
  scheduler = AsyncIOScheduler()
  scheduler.add_job(deneme, "cron", year="*", month="*", minute=19)
  scheduler.start()
  asyncio.get_event_loop().run_forever()

Yani deneme fonsksiyonum async olarak tanımlı. Ana dizinde şu şekilde çalıştırıyorum.

#diğer kodlar ....
startCron()
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=7000)

Böyle yaptığımda startCron() çalışıyor, fakat alt satıra geçmiyor. Sadece cron’lar ateşleniyor. Bunun nedeni sanırsam async fonksiyonlardan kaynaklı. Benim hem cron’u ateşlemem hem de app.run() ile api’leri aktif hale getirmem gerekiyor.
Eğer

  asyncio.get_event_loop().run_forever()

Satırına kaldırırsam cron’lar ateşlenmiyor. Bu satırı eklediğimde ise async fonksiyonlar sanırsam sonsuz döngüye giriyor. Nasıl bir çözüm uygulamam gerekiyor ?

startCron'u, yani async islemler loop’unu ayri bir thread’de calistirman lazim. threading.Thread().run(target=startCron) gibi bir sey; ornegini forumda veya dokumentasyonda bulabilirsin.

Alternatif app'i async calistirmak.

1 Beğeni

Hocam tekrardan selamlar. Dediğiniz gibi ilk olarak thread ile yapmaya çalışmıştım. Kurduğum yapı:
1-) Ana Dizin

def runApp():
    if __name__ == '__main__':
        app.run(threaded=True)

crons = Thread(target=cronRun)
flaskApp = Thread(target=runApp)

crons.start()
flaskApp.start()

2-)Cron

def cronRun():
    print("cron'a girdi")
    scheduler = AsyncIOScheduler()
    scheduler.add_job(deneme, "interval", seconds=2)
    scheduler.start()
    asyncio.get_event_loop().run_forever()

Rotalar çalışıyor. Fakat cron ateşlenmeyip şu hatayı veriyor:

RuntimeError: There is no current event loop in thread 'Thread-1'.

Bu hatayı çözemeyip pes etmiştim.
Şimdide dediğiniz gibi app.run() işlemini async içine almaya çalıştım. Yapı şu şekilde:

app = Flask(__name__, template_folder='templates')
CORS(app)

async def runApp():
    if __name__ == '__main__':
        app.run(threaded=True)

runApp()
cronRun()
asyncio.get_event_loop().run_forever()

Burda da cron’lar ateşleniyor fakat app.run() işlemi olmuyor. Şöyle bir hata karşıma çıkıyor:

RuntimeWarning: coroutine 'runApp' was never awaited
  runApp()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

Sanırsam await işlemi yapmadığım için böyle bir şey oluyor. await app.run() olarak kullanmakta burda pek doğru gelemedi ? Bu durumda ne yapmam gerekiyor ? Teşekkür ederim.

Bunun cozumleri internette var. Olmadi event loop’u ana thread’de calistirip Flask app’i yeni thread’de calistirmayi deneyebilirsin.(flaskApp.start(); cronRun())

Boyle basit bir cevrim olmaz. Flask’i mevcut async event loop’u icinde calisacak sekilde ayarlamak lazim. Mumkun mu bilmiyorum bile; dokumentasyona bakmak lazim. (Ustteki mesaja kadar Flask kullanildigini bilmiyordum.)

En basit şekilde bu işimi gördü şimdilik. Teşekkür ederim.