Matt Sergeant wrote:
Because otherwise hooks are re-loaded on every connection (register() needs re-run on every mail) which is a huge performance detriment.
Then we need to rethink that architecture; would it be acceptable to return immediately if hooks are already defined (instead of just warning and redefining)? That was the original plan, but it may have been messed up over time.
I don't think per-object hooks ever worked right or were useful anyway were they?
The problem was that some parts of the codebase still assumed per-object hooks, which is why auth was not working correctly. If you want to go that route, you'd need to go through and find all $self->{hooks} and replace them with $self->hooks() like Hanno suggested, but also have a setter for actually registering the hooks. It also means that the hooks listing is only available inside the Qpsmtpd:: scope itself, and I haven't checked where else that was accessed in the core code.
My long-term goal was to write a generic RFC-2822 event loop that could be extended at both load and run time, rather than having some phases in core and some as hooks (think of how auth and TLS are currently manhandled into the core, the latter by hooking unrecognized commands). This would mean each transaction might have a base set of phases/hooks (to correspond to the bare EHLO/FROM/TO/DATA/QUIT set), and based on what was registered at load time, would gain additional phases/hooks inbetween. Specific plugins would also be able to add hooks (like greylisting or tiergrube) in a Just In Time model per transaction.
For greatest performance (obviously something near and dear to your heart), you would configure all plugins to have load-time only effects and only pay that price once. Other people might have different concerns...
John