Code

Opened 6 years ago

Closed 16 months ago

Last modified 5 months ago

#8085 closed Bug (needsinfo)

call_command('runserver') executes management command twice.

Reported by: ericholscher Owned by:
Component: Core (Management commands) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Someday/Maybe
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When you use runserver in a management command, it executes the code in the management command twice. This is cited in the testserver management command:

32 	        # Run the development server. Turn off auto-reloading because it causes
33 	        # a strange error -- it causes this handle() method to be called
34 	        # multiple times.
35 	        shutdown_message = '\nServer stopped.\nNote that the test database, %r, has not been deleted. You can explore it on your own.' % db_name
36 	        call_command('runserver', addrport=addrport, shutdown_message=shutdown_message, use_reloader=False)

I ran into this as well, and I'm just putting it in here so hopefully someone sees it and fixes it.

Attachments (0)

Change History (13)

comment:1 Changed 6 years ago by ericholscher

  • Component changed from Uncategorized to django-admin.py runserver
  • milestone set to post-1.0
  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to ericholscher
  • Patch needs improvement unset
  • Status changed from new to assigned

Known issue, but has to do with multi-threading in the auto_reload stuff.

comment:2 Changed 6 years ago by ericholscher

  • Triage Stage changed from Unreviewed to Someday/Maybe

comment:3 Changed 5 years ago by ericholscher

  • Owner ericholscher deleted
  • Status changed from assigned to new

comment:4 Changed 5 years ago by anonymous

  • milestone post-1.0 deleted

Milestone post-1.0 deleted

comment:5 Changed 4 years ago by tiberiu_ichim

  • Triage Stage changed from Someday/Maybe to Unreviewed

One issue I have related to this: the second time the code is executed, in my setup (I'm using zc.buildout, and I have Django listed as an egg dependency for my own egg), it can't find the django modules.

comment:6 Changed 4 years ago by tiberiu_ichim

My problem is solved if I run "runserver" with the --noreload option, so the problem must be in django.utils.autoreloader.
Some details about my setup: my python is actually a script generated with zc.recipes.egg's "interpreter" option. This script inserts all my egg dependencies in the sys.path, then calls an execfile(mymodule). I think the autoreloader only looks at the module that was executed (manage.py) but ignores the special settings for sys.path that that module had.

comment:7 Changed 4 years ago by SmileyChris

  • Triage Stage changed from Unreviewed to Someday/Maybe

comment:8 Changed 3 years ago by gabrielhurley

  • Component changed from django-admin.py runserver to Core (Management commands)

comment:9 Changed 3 years ago by lukeplant

  • Severity set to Normal
  • Type set to Bug

comment:10 Changed 2 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:11 Changed 2 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:12 Changed 16 months ago by aaugustin

  • Resolution set to needsinfo
  • Status changed from new to closed

Reading this ticket, I don't understand what the problem is, or what the fix should be.

comment:13 Changed 5 months ago by Hipikat

Hi. I just encountered this, too…

The problem is just that the reloader starts news threads, and so… django.utils.autoreload.restart_with_reloader calls new_environ["RUN_MAIN"] = 'true' and then django.utils.autoreload.python_reloader knows to look, for if os.environ.get("RUN_MAIN") == "true": then it's in a spawned thread. The solution is just to check that RUN_MAIN is False in your handle method…

# some_app.management.commands.some_command.py
import os       
from django.core.management.commands import runserver
class Command(runserver.Command):
        def handle(self, *args, **options):
            if not os.environ.get('RUN_MAIN', False):
                # some_code 
            super(Command, self).handle(*args, **options)

Anyway, I'm guessing this is too esoteric and internal to justify a note anywhere in the main documentation, but I'm not going to be the last person to get stumped by it, so commenting on this issue seemed like the appropriate place to mention the solution? :)

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.