daphne icon indicating copy to clipboard operation
daphne copied to clipboard

ValueError: Unknown endpoint type: 'fd' - Daphne 4.2.0

Open d3al opened this issue 11 months ago • 16 comments

Deployed our project today and got this error. Daphne was updated 5 hours ago so we rolled it back to 4.1.2 and the issue went away.

Deployed in docker python3.10 image, ubuntu 22.04 host, tried 4.2.0 again and got the error. I also did a full update and rebooted to make sure the machine was current.

This is our launch command initiated from supervisor. This hasn't changed in years.

command=/opt/services/djangoapp/src/.venv/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers project.asgi:application

2025-05-16 19:25:02,473 INFO     Starting server at fd:fileno=0, unix:/run/daphne/daphne0.sock
2025-05-16 19:25:02,473 INFO     HTTP/2 support enabled
2025-05-16 19:25:02,473 INFO     Configuring endpoint fd:fileno=0
Traceback (most recent call last):
  File "/opt/services/djangoapp/src/.venv/bin/daphne", line 8, in <module>
    sys.exit(CommandLineInterface.entrypoint())
  File "/opt/services/djangoapp/src/.venv/lib/python3.10/site-packages/daphne/cli.py", line 171, in entrypoint
    cls().run(sys.argv[1:])
  File "/opt/services/djangoapp/src/.venv/lib/python3.10/site-packages/daphne/cli.py", line 291, in run
    self.server.run()
  File "/opt/services/djangoapp/src/.venv/lib/python3.10/site-packages/daphne/server.py", line 130, in run
    ep = serverFromString(reactor, str(socket_description))
  File "/opt/services/djangoapp/src/.venv/lib/python3.10/site-packages/twisted/internet/endpoints.py", line 1844, in serverFromString
    nameOrPlugin, args, kw = _parseServer(description, None)
  File "/opt/services/djangoapp/src/.venv/lib/python3.10/site-packages/twisted/internet/endpoints.py", line 1764, in _parseServer
    plugin = _matchPluginToPrefix(
  File "/opt/services/djangoapp/src/.venv/lib/python3.10/site-packages/twisted/internet/endpoints.py", line 1779, in _matchPluginToPrefix
    raise ValueError(f"Unknown endpoint type: '{endpointType}'")
ValueError: Unknown endpoint type: 'fd'

d3al avatar May 16 '25 20:05 d3al

Hi @d3al. Thanks for the report.

There's no obvious change here that would cause this, so I'll need to see if I can reproduce it.

Just for completeness can you please confirm the twisted version in the two scenarios? Thanks.

carltongibson avatar May 17 '25 05:05 carltongibson

Twisted = 24.11.0 with extras, http2, tls. Channels with extras daphne

I can do more testing this weekend. 

On Fri, 2025-05-16 at 22:43 -0700, Carlton Gibson wrote:

carltongibson left a comment (django/daphne#557) [1] Hi @d3al [2]. Thanks for the report. There's no obvious change here that would cause this, so I'll need to see if I can reproduce it. Just for completeness can you please confirm the twisted version in the two scenarios? Thanks. — Reply to this email directly, view it on GitHub [1], or unsubscribe [3]. You are receiving this because you were mentioned.Message ID: @.***>

[1] (django/daphne#557) https://github.com/django/daphne/issues/557#issuecomment-2888107496 [2] @d3al https://github.com/d3al [3] unsubscribe https://github.com/notifications/unsubscribe-auth/AORJFJ742UB6MAWTEGTPV63263EAXAVCNFSM6AAAAAB5JTGC4CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQOBYGEYDONBZGY

d3al avatar May 17 '25 06:05 d3al

OK, so it looks like the daphne/twisted/plugins/fd_endpoint.py plugin is not being picked up properly. This could be a follow up to #510.

carltongibson avatar May 17 '25 06:05 carltongibson

Original issue there was #506

carltongibson avatar May 17 '25 09:05 carltongibson

The fd_enpoint.py file is present in the installed package

(venv) $ pip freeze | grep daphne
daphne==4.2.0
(venv) $ ls -la /tmp/venv/lib/python3.10/site-packages/daphne/twisted/plugins/
total 16
drwxrwxr-x 3 pandafy pandafy 4096 Jun  6 18:02 ./
drwxrwxr-x 3 pandafy pandafy 4096 Jun  6 18:02 ../
-rw-rw-r-- 1 pandafy pandafy  814 Jun  6 18:02 fd_endpoint.py
drwxrwxr-x 2 pandafy pandafy 4096 Jun  6 18:02 __pycache__/

So, this might be different from #506?

pandafy avatar Jun 06 '25 12:06 pandafy

Temporary copying the fd_endpoint.py from daphne to twisted fixed this for me.

cp daphne/twisted/plugins/fd_endpoint.py twisted/plugins/

ronnievdc avatar Jun 16 '25 07:06 ronnievdc

@ronnievdc Yes, that'll fix it. Question is why that file is getting installed for some people but not others. 🤔

carltongibson avatar Jun 16 '25 07:06 carltongibson

@carltongibson I think it depends if the twisted directory is cleared or not. So if twisted is not reinstalled it could keep the fd_endpoint.py in the plugins folder.

ronnievdc avatar Jun 16 '25 08:06 ronnievdc

@ronnievdc Makes sense, yes. So it's basically the same packaging issue from before.

I had thought we'd resolved this. (Grrr packaging...)

Setuptools configuration it is... 👀

carltongibson avatar Jun 16 '25 08:06 carltongibson

@carltongibson Would it be possible to add the plugin via de alternate-plugin-packages method. This makes the packaging easier.

https://docs.twisted.org/en/twisted-15.2.1/core/howto/plugin.html#alternate-plugin-packages

from twisted.plugin import pluginPackagePaths
__path__.extend(pluginPackagePaths(__name__))
__all__ = []

ronnievdc avatar Jun 16 '25 09:06 ronnievdc

@ronnievdc I think the first step is a tox env, demonstrating that the install is wrong. (The plugin file should be correctly installed. I'm not sure it's necessary to start a Daphne process with the fd flag as well, but it might not hurt.)

From there we can look at different strategies to fix. (AFAICS the correct setuptools configuration should be sufficient 🤔)

carltongibson avatar Jun 16 '25 11:06 carltongibson

@carltongibson I have no experience in tox, but i was able to reproduce this with minimal Docker.

Trying various combinations with the twisted plugins had no success.

The plugin is only listed when calling getPlugIns with daphne.twisted.plugins as package. But serverFromString calls the method without any package.

import daphne.twisted.plugins as package
getPlugIns(IStreamServerEndpointStringParser, package)

Would you be open to update the Server.run method with the following code to circumvent the twisted plugins and directly call the plugin?

from .twisted.plugins.fd_endpoint import parser
from twisted.internet.endpoints import _parse

class Server:
    def run(self):
        [...SNIP...]
            try:
                ep = serverFromString(reactor, str(socket_description))
            except ValueError:
                args, kw = _parse(str(socket_description))
                args = args[1:]
                ep = parser.parseStreamServer(reactor, *args, **kw)

Example repo: https://github.com/ronnievdc/daphne-issue-557

ronnievdc avatar Jun 16 '25 13:06 ronnievdc

@ronnievdc I added a test for the plugin installation in #562. This should let us experiment with the packaging config to ensure we have the right solution.

carltongibson avatar Jun 17 '25 06:06 carltongibson

OK, so this looks like a regression in #542. The setuptools configuration wasn't currently migrated from setup.cfg to pyproject.toml.

carltongibson avatar Jun 17 '25 07:06 carltongibson

@carltongibson The solution seems to work in my docker test setup.

https://github.com/ronnievdc/daphne-issue-557/commit/82a92c31dd186a1ef60b6fd338de45126ee16fa8

ronnievdc avatar Jun 17 '25 09:06 ronnievdc

Thanks for giving it a test @ronnievdc

carltongibson avatar Jun 17 '25 09:06 carltongibson