django / asgi_ipc

IPC-based ASGI channel layer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Semaphores don't get created on Alpine Linux

mheppner opened this issue · comments

Using Alpine Linux 3.6, semaphores don't seem to be getting created in /dev/shm:

# ls -l /dev/shm
total 8
-rw-------    1 root     root      20971520 Oct 18 15:34 asgi-groups
-rw-------    1 root     root     104857600 Oct 18 15:34 asgi-messages

Using the same versions listed below on Debian Jessie, the semaphores and shared memory appear in /dev/shm:

# ls -l /dev/shm
total 12
-rw------- 1 root root  20971520 Oct 18 15:38 asgi-groups
-rw------- 1 root root 104857600 Oct 18 15:38 asgi-messages
-rw------- 1 root root        32 Oct 18 15:38 sem.asgi-groups
-rw------- 1 root root        32 Oct 18 15:38 sem.asgi-messages

I'm not sure if it's related to the missing semaphore, but the generated value ends up being None. In Debian, I can at least see the value as {}.

Once daphne or a second worker are started, then the value can't be unpickled and results in the stack trace below.


On Alpine:

Python 3.6.1 (default, May  2 2017, 15:16:41)
[GCC 6.3.0] on linux

On Debian:

Python 3.6.3 (default, Oct 10 2017, 02:29:16)
[GCC 4.9.2] on linux

Both:

asgi-ipc==1.4.1
asgiref==1.1.
channels==1.1.8
daphne==1.3.0
Django==1.11.6
posix-ipc==1.0.0

From Alpine:

  File "./manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/usr/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python3.6/site-packages/channels/management/commands/runworker.py", line 83, in handle
    worker.run()
  File "/usr/lib/python3.6/site-packages/channels/worker.py", line 87, in run
    channel, content = self.channel_layer.receive_many(channels, block=True)
  File "/usr/lib/python3.6/site-packages/asgiref/base_layer.py", line 43, in receive_many
    return self.receive(channels, block)
  File "/usr/lib/python3.6/site-packages/asgi_ipc/core.py", line 83, in receive
    message = self.message_store.pop(channel)
  File "/usr/lib/python3.6/site-packages/asgi_ipc/store.py", line 123, in pop
    with self.mutate_value() as value:
  File "/usr/lib/python3.6/contextlib.py", line 82, in __enter__
    return next(self.gen)
  File "/usr/lib/python3.6/site-packages/asgi_ipc/store.py", line 57, in mutate_value
    value = pickle.load(self.mmap)
_pickle.UnpicklingError: invalid load key, '\xff'

Found the problem. In Alpine, semaphores don't get prefixed with sem., so the path is being overwritten in the constructor when it creates the shared memory. Maybe this is a difference between musl and glibc?

Can something maybe be added to further distinguish the two? Even though it's redundant on glibc-based Linux version, maybe just append '-semaphore' to the end of the path?

Shared memory stuff is so underspecified I'm sure it's just a difference. Fix shouldn't be too hard, but it might have to wait a bit until I get to rewriting the channel layers to be async.