[Date Prev][Date Next]
Re: controls and dynamic support
Pierangelo Masarati wrote:
Howard Chu wrote:
I was thinking about how both pagedresults and server-side sorting
could be accomplished using overlays, and the idea is simple enough.
But one of the more awkward aspects of adding new controls is
plugging them into the Operation structure so they can be easily
referenced by other code. I recall how OpenSSL handles various
OID-based entities - it has its own internal registry and assigns
small integers (NIDs) for each one. I think we need a similar
mechanism for slapd.
Specifically, the register_supported_control function should return
the index of the control in slapd's internal table. The Operation
structure should have an array
.. or void *o_controls[NID_MAX]; ?
I guess that would be OK. Any reason you prefer that over dynamically
sizing the array? (I prefer to avoid hard limits, and I don't see a
compelling need to limit this one.)
that is preallocated to a size equal to the number of currently
registered controls. Each element of the array will be set by the
control's parser to point to a control-specific structure to carry
whatever state that control needs. (Only controls that were actually
received will have non-NULL entries in the array.)
Certain controls that we decide to leave inside the core can have
well-known variables carrying their assigned control IDs (CIDs):
do you mean something like
#define CONTROL_ABSENT NULL
#define CONTROL_PRESENT 0x1
#define o_managedsait o_controls[slap_control.sc_id_manageDSAIT]
((int)(op)->o_managedsait == CONTROL_PRESENT)
Yes, something like that. Except for presence tests I would just use
#define get_manageDSAit(op) ((op)->o_managedsait != CONTROL_ABSENT)
Others should be migrated out to private files specific to their
implementation. (I of course want to migrate all the syncrepl state
info out as well.)
So a pagedResults overlay would register its control and save the
returned index. Its parser function would allocate a private
structure and assign its address to op->o_controls[pagedresults_cid]
on an incoming operation, and all of the overlay code that needs to
reference the control parameters can find it there.
We can also export a find_ctrl function that returns the CID for a
given OID, etc.
As for the actual controls...
For server-side sorting all you need is an overlay that intercepts
search responses and builds a sorted list before actually returning
results to a client. The biggest issue here is configuring how much
memory it's allowed to consume per search.
For paged results you could be really gross and actually suspend the
current thread at the end of a page. (Of course, this means tying up
threads for some amount of time. Not so friendly.) That is, the
overlay's search response callback just waits on a condition variable
when it gets to the page limit. The overlay's search handler checks
for any currently suspended operations when it receives a continuing
paged results request, and signals the condition if it finds the
match. There can be an idletimeout runtask that abandons operations
that have been suspended for too long. It's a rather coarse-grained
approach to saving search state, but it would work for all backends
without needing to redesign them all.
No objection; except, to avoid some of the problems you highlighted
with, e.g. pagedResults, we could use the overlay approach only where
the undelying backend does not provide a more effective mechanism,
e.g. for back-bdb (by saving the last sent ID) or back-ldap (where the
control is simply propagated to the proxied DSA). Or, by
enabling/disabling the overlay one can select to use the control or
leave it to the backend.
-- Howard Chu
Chief Architect, Symas Corp. Director, Highland Sun
Symas: Premier OpenSource Development and Support