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

Task which Triggers Multiprocessing #82

Open
diegofcoelho opened this issue Apr 7, 2017 · 6 comments
Open

Task which Triggers Multiprocessing #82

diegofcoelho opened this issue Apr 7, 2017 · 6 comments

Comments

@diegofcoelho
Copy link
Contributor

diegofcoelho commented Apr 7, 2017

Is it possible to trigger a multiprocessing task? I tried but run it as a django management command makes it finish with no fail (and also no task performed) after a few seconds.

@diegofcoelho diegofcoelho changed the title Multi thread task Task which Triggers Multiprocessing Apr 19, 2017
@diegofcoelho
Copy link
Contributor Author

I am kinda answering my question, although not completely satisfied.

I manage to start a multithreading task with dango-chroniker by using the mysterious and undocumented
from multiprocessing.pool import ThreadPool but still no success with true multiprocess.

@chrisspen
Copy link
Owner

chrisspen commented Apr 19, 2017 via email

@diegofcoelho
Copy link
Contributor Author

diegofcoelho commented Apr 20, 2017

I meant that I wanted to start a multiprocessing task using chroniker but the processes shuts after no activity is performed.

Although a multithread was possible using the library I described previsouly, it wasn't possible using the standard library and multiprocessing (true isolated processes) can't work anyhow..

@chrisspen
Copy link
Owner

You need to give me a little more detail about how you're "starting a multiprocessing task", because that could mean almost anything. Like I said, all jobs are run as a separate process, so you don't need to do any more work than just implement your Django management command. If you're using nohup or screen or some other method to launch a process, it might be happening. However, the chroniker job won't track those and will immediately return after the process launches.

@diegofcoelho
Copy link
Contributor Author

diegofcoelho commented Apr 22, 2017

I am afraid I can not provide a piece of working code as a perfect representation of what I was intending but following the examples on Python Docs, I could use the code below:

from multiprocessing import Pool
from django.core.management.base import BaseCommand
import time
import os

class Command(BaseCommand):
    @staticmethod
    def f(x):
        return x*x

    def handle(self, *args, **options):
        # start 4 worker processes
        with Pool(processes=4) as pool:

            # print "[0, 1, 4,..., 81]"
            print(pool.map(self.f, range(10)))

            print("For the moment, the pool remains available for more work")

        # exiting the 'with'-block has stopped the pool
        print("Now the pool is closed and no longer available")

Then the chroniker thread/process would stay up until the processes finished and even if we don't bother to get messages from the standalone process, it should be executed.
The problem is that is doesn't.

The closest it gets can be seen in the code below:

from django.core.management.base import BaseCommand

from multiprocessing import Pool
from app.models import car


class Command(BaseCommand):

    def f(x):
        print(x)

    def handle(self, *args, **options):
        # start 4 worker processes
        with Pool(processes=1) as pool:
            l = list(car.objects.all())
            # print "[0, 1, 4,..., 81]"
            print(pool.map(self.f, l))

            print("For the moment, the pool remains available for more work")

        # exiting the 'with'-block has stopped the pool
        print("Now the pool is closed and no longer available")

But its execution triggers:

Traceback (most recent call last):
  File "\Python\Python35-32\lib\multiprocessing\process.py", line 249, in _boots
trap
    self.run()
  File "\Python\Python35-32\lib\multiprocessing\process.py", line 93, in run self._target(*self._args, **self._kwargs)
  File "\Python\Python35-32\lib\multiprocessing\pool.py", line 108, in worker task = get()
  File "\Python\Python35-32\lib\multiprocessing\queues.py", line 345, in get return ForkingPickler.loads(res)
  File "\app\management\commands\DjChMP.py", line 4, in <module>
    from app.models import car
  File "app\models.py", line 20, in <module>
    from django.contrib.auth.models import User
  File "\Python\Python35\site-packages\django\contrib\auth\models.py", line 4, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "\Python\Python35\site-packages\django\contrib\auth\base_user.py", line 52, in <module>
    class AbstractBaseUser(models.Model):
  File "\Python\Python35\site-packages\django\db\models\base.py", line 105, in __new__
    app_config = apps.get_containing_app_config(module)
  File "\Python\Python35\site-packages\django\apps\registry.py", line 237, in get_conta
ining_app_config
    self.check_apps_ready()
  File "\Python\Python35\site-packages\django\apps\registry.py", line 124, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

BTW, there are a few things on chroniker that bothers me a bit and would like to show you.. Should I open a issue for each or a all-in-one? With a some instructions I can try to cooperate with the project but I have no idea how a python environment setup for that would be..

@chrisspen
Copy link
Owner

chrisspen commented Apr 22, 2017

Thanks for the detail. That's interesting. In general, I don't see why that wouldn't work. The error you're getting is because the new process is trying to access Django settings, but doesn't have the right path and/or Django settings module name set.

And by all means, feel free to open issues for any bugs or design issues you see.

The way I resolve bugs is to reproduce the error in a unittest, which would be called like:

export TESTNAME=.testSomeIssue; tox -e py35-django110

and then fix the issue and confirm the test passes. However, bugs involving multiprocessing can be tricky to fix because Django's test runner has a built-in transaction which only works from the main process, so trying to access any Django tables or settings in processes outside of that will get you strange errors like the one you reported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants