0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【備忘録】Djangoの定期実行で2回呼ばれてしまう修正

Posted at

はじめに

こんにちは、エンジニアのkeitaMaxです。python初心者がDajngoを使ってみようと思って色々試しています。

今回はDjangoを使用している時に定期実行を作成していたのですが、なぜか2回実行されてしまうという問題にあたったのでそれの解決した時のことを備忘録として書こうと思います。

誤っていることを書いていたらコメントしてくれると嬉しいです。

やっていたこと

apschedulerを使用して定期的に実行をしようとしていました。

apps.py
import os
from django.apps import AppConfig

class AppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'app'

    def ready(self):
        from .management.commands.example import start
        start()

apps.pyを上記のようにして、example.pyは以下のように5秒ごとに"Hello World!"を出すようにしていました。

example.py
def test():
    logger.info("Hello World!")

def start():
    scheduler = BackgroundScheduler()
    scheduler.add_job(test, 'interval', seconds=5)
    scheduler.start()

これをdocker-compose.yml


  backend:
    container_name: backend
    build:
      context: ./docker
      dockerfile: Dockerfile
    command: python3 manage.py runserver 0.0.0.0:8000

こんな感じで起動していました。

原因

どうやらrunserver はソースコードの変更を検知して自動リロードするため、実際にはプロセスが2回起動されてしまうらしいです。

  1. 最初のプロセスはコード監視専用の親プロセス
  2. その後、実際にアプリを動かす子プロセスが起動

そして、ready() はこの両方で呼び出されるため、start() が2回実行されてしまっているらしです。

解決策

apps.pyのready() を 子プロセスだけ実行するように以下のように修正しました。

apps.py
import os
from django.apps import AppConfig

class AppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'app'

    def ready(self):
        if os.environ.get('RUN_MAIN') == 'true':  # 子プロセスだけ実行するように修正
            from .management.commands.scrape import start
            start()

これで2回実行されることは無くなりました。

おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました!

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?