Re: Discussion on a LISTEN-ALL syntax - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: Discussion on a LISTEN-ALL syntax |
Date | |
Msg-id | 737106.1734732462@sss.pgh.pa.us Whole thread Raw |
In response to | Re: Discussion on a LISTEN-ALL syntax (Trey Boudreau <trey@treysoft.com>) |
Responses |
Re: Discussion on a LISTEN-ALL syntax
Re: Discussion on a LISTEN-ALL syntax Re: Discussion on a LISTEN-ALL syntax |
List | pgsql-hackers |
Trey Boudreau <trey@treysoft.com> writes: > My first pass at the documentation looks like this: > <para> > The special wildcard <literal>*</literal> cancels all listener > registrations for the current session and replaces them with a > virtual registration that matches all channels. Further > <command>LISTEN</command> and <command>UNLISTEN <replaceable > class="parameter">channel</replaceable></command> commands will > be ignored until the session sees the <command>UNLISTEN *</command> > command. > </para> Hmph. After thinking about it a bit I have a different idea (and I see David has yet a third one). So maybe this is more contentious than it seems. But at any rate, I have two fundamental thoughts: * "Listen to all but X" seems like a reasonable desire. * The existing implementation already has the principle that you can't listen to a channel more than once; that is, LISTEN foo; LISTEN foo; -- this is a no-op, not a duplicate subscription Therefore I propose: * "LISTEN *" wipes away all previous listen state, and sets up a state where you're listening to all channels (within your database). * "UNLISTEN *" wipes away all previous listen state, and sets up a state where you're listening to no channels (which is the same as it does now). * "LISTEN foo" adds "foo" to what you are listening to, with no effect if you already were listening to foo (whether it was a virtual or explicit listen). * "UNLISTEN foo" removes "foo" from what you are listening to, with no effect if you already weren't listening to foo. This is just about the same as the current behavior, and it makes "LISTEN *" act the same as though you had somehow explicitly listed every possible channel. Which I think is a lot cleaner than conceptualizing it as an independent gating behavior, as well as more useful because it'll permit "all but" behavior. The implementation of this could be something like struct { bool all; /* true if listening to all */ List *plus; /* channels explicitly listened */ List *minus; /* channels explicitly unlistened */ } ListenChannels; with the proviso that "plus" must be empty if "all" is true, while "minus" must be empty if "all" is false. The two lists are always empty right after LISTEN * or UNLISTEN *, but could be manipulated by subsequent channel-specific LISTEN/UNLISTEN. (Since only one list would be in use at a time, you could alternatively combine "plus" and "minus" into a single list of exceptions to the all/none state. I suspect that would be confusingly error-prone to code; but perhaps it would turn out elegantly.) One other thing that needs to be thought about in any case is what the pg_listening_channels() function ought to return in these newly-possible states. regards, tom lane
pgsql-hackers by date: