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

Executable name for Dramatiq on Windows is "dramatiq.exe" #109

Open
pkimber opened this issue Jun 23, 2021 · 4 comments
Open

Executable name for Dramatiq on Windows is "dramatiq.exe" #109

pkimber opened this issue Jun 23, 2021 · 4 comments

Comments

@pkimber
Copy link

pkimber commented Jun 23, 2021

The _resolve_executable method in django_dramatiq/management/commands/rundramatiq.py will find venv\Scripts\dramatiq, but on Windows it needs to find venv\Scripts\dramatiq.exe

Can we update the code in: 4c70775

@pkimber
Copy link
Author

pkimber commented Jun 23, 2021

  1. The python path isn't being searched because I am using subprocess.Popen

  2. The old _resolve_executable builds the path to venv\Scripts\dramatiq (as long as sys.executable returns something):

def _resolve_executable(self, exec_name):
    bin_dir = os.path.dirname(sys.executable)
    if bin_dir:
        return os.path.join(bin_dir, exec_name)
    return exec_name

The new version of _resolve_executable only updates the executable_path if the file exists (if os.path.isfile(exec_path)). For Windows, we need to look for dramatiq.exe.

@pkimber
Copy link
Author

pkimber commented Jun 28, 2021

I solved the issue by adding to the _resolve_executable method in django_dramatiq/django_dramatiq/management/commands/rundramatiq.py:

# fall back to default behaviour (from earlier versions)
return os.path.join(bin_dir, exec_name)

Here is the whole method:

    def _resolve_executable(self, exec_name):
        bin_dir = os.path.dirname(sys.executable)
        if bin_dir:
            for d in [bin_dir, os.path.join(bin_dir, "Scripts")]:
                exec_path = os.path.join(d, exec_name)
                if os.path.isfile(exec_path):
                    return exec_path
            # fall back to default behaviour (from earlier versions)
            # ref https://github.com/Bogdanp/django_dramatiq/issues/109
            return os.path.join(bin_dir, exec_name)
        return exec_name

I tried to write a test, but failed. Would you like me to create a pull request for the method (without tests)?

@Bogdanp
Copy link
Owner

Bogdanp commented Aug 8, 2021

I'm confused about why the fallback would fix the problem in this case. exec_name is always either dramatiq or dramatiq-gevent so even with the fallback in place, it sounds like it would resolve to the wrong path. What am I missing?

pkimber added a commit to pkimber/django_dramatiq that referenced this issue Aug 30, 2023
@pkimber
Copy link
Author

pkimber commented Sep 1, 2023

Not sure I am helping, but I wrote a Django management command with two versions of _resolve_executable (_resolve_executable and _resolve_executable_updated):

import os
import sys

from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = "Dramatiq - process is stopping #5668"

    def _resolve_executable(self, exec_name):
        bin_dir = os.path.dirname(sys.executable)
        if bin_dir:
            for d in [bin_dir, os.path.join(bin_dir, "Scripts")]:
                exec_path = os.path.join(d, exec_name)
                if os.path.isfile(exec_path):
                    return exec_path
        return exec_name

    def _resolve_executable_updated(self, exec_name):
        bin_dir = os.path.dirname(sys.executable)
        if bin_dir:
            for d in [bin_dir, os.path.join(bin_dir, "Scripts")]:
                exec_path = os.path.join(d, exec_name)
                if os.path.isfile(exec_path):
                    return exec_path
            # fall back to default behaviour (from earlier versions)
            # ref https://github.com/Bogdanp/django_dramatiq/issues/109
            return os.path.join(bin_dir, exec_name)
        return exec_name

    def handle(self, *args, **options):
        self.stdout.write(f"{self.help}")
        executable_name = "dramatiq"
        result = self._resolve_executable(executable_name)
        self.stdout.write("_resolve_executable:")
        self.stdout.write(f"{result}")
        result = self._resolve_executable_updated(executable_name)
        self.stdout.write("_resolve_executable_updated:")
        self.stdout.write(f"{result}")
        self.stdout.write(f"{self.help} - Complete")

On my Windows server, the return value is different:

(venv) C:\kb>python manage.py 5668-dramatiq-process-stopping
_resolve_executable:
dramatiq
_resolve_executable_updated:
c:\kb\venv\Scripts\dramatiq 

I am starting Dramatiq using a Windows service (win32serviceutil.ServiceFramework) and Dramatiq will not start unless we have the full path i.e. c:\kb\venv\Scripts\dramatiq.

Sorry... I am not being much help here, but thought I would share.

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