PaulGilmartin / django-pgpubsub

A distributed task processing framework for Django built on top of the Postgres NOTIFY/LISTEN protocol.
Other
245 stars 12 forks source link

Psycopg3 support #56

Closed NathanSmeltzer closed 2 months ago

NathanSmeltzer commented 1 year ago

Are there plans to support Psycopg 3? I tried installing both psycopg2 and psycopg[c] (Psycopg3) but received this error which seems due to Psycopg 3 not having a poll method for its Connection class:

File "/usr/local/lib/python3.10/site-packages/pgpubsub/listen.py", line 71, in process_notifications
    pg_connection.poll()
AttributeError: 'Connection' object has no attribute 'poll'

Supporting this would clear up some confusion as cookiecutter django now installs Psycopg 3 by default. Libraries like django-debug-toolbar support both versions.

PaulGilmartin commented 1 year ago

Yes I will try to support this in the next version of this library. I haven't worked with psycopg3 yet, so I'm not sure of the work involved and how practical it will be to support both 2 and 3 on the same version, but I will definitely look into it for the next release of this library (hoping that's sometime at the end of summer).

PaulGilmartin commented 9 months ago

I started looking at this yesterday. It definitely seems like it's not going to be a trivial change to start supporting psycopg3, but of course we should strive to do so. As well as the poll API no longer being there, connection.notifies is now a callable which returns a generator, which is a departure from the previous version. I also get a strange issue where if I try to fetch from the generator it just hangs forever. I saw similar complaints and it looks like this may have been addressed in psycogp3 v3.2, but that isn't a production release yet.

@romank0 I know you're using a forked version of this library. Have you tried it with psycopg3 yet at all?

romank0 commented 9 months ago

@romank0 I know you're using a forked version of this library. Have you tried it with psycopg3 yet at all?

No, we are still using v2.

jayjlow commented 8 months ago

I made some alterations to the process_notifications function:

def process_notifications(pg_connection):
    # pg_connection.poll()
    gen = pg_connection.notifies()
    for notification in gen:
        with transaction.atomic():
            for processor in [
                NotificationProcessor,
                LockableNotificationProcessor,
                NotificationRecoveryProcessor,
            ]:
                try:
                    processor = processor(notification, pg_connection)
                except InvalidNotificationProcessor:
                    continue
                else:
                    processor.process()
                    break
        if notification.payload == "stop":
            gen.close()

Not sure if there is more to do, but this at least got the notify working for me.

PaulGilmartin commented 3 months ago

@jayjlow Thanks for the tip! I'll take that into account when I return to this task.

PaulGilmartin commented 2 months ago

Support for psycogp3 has been implemented in v1.3.0 of this library thanks to @romank0. See the installation docs for more details. Note that when using psycogp3, we need to perform a query to fetch the notifications when listening. This is due to differences in the library which currently have made it impossible (as far as we can see) to do it client side like on psycopg2.