'Return a ``MsgId`` instance, it asynchronous API.
The ``MsgId`` instance can be safely used in a call to ``result3()``.
To work with ``result3()`` API in predictable manner, the same LDAP
connection is needed which originally provided the ``msgid``. So, this
method wraps the existing connection and ``msgid`` in a new ``MsgId``
instance. The connection associated with ``search_ext`` is released
once last hard reference to the ``MsgId`` instance is freed.'

def search_ext(self, base, scope, filterstr='(objectClass=*)', attrlist=None, attrsonly=0, serverctrls=None, clientctrls=None, timeout=(-1), sizelimit=0):

    conn_ctxt = self._get_pool_connection()
    conn = conn_ctxt.__enter__()
    try:
        msgid = conn.search_ext(base, scope, filterstr, attrlist, attrsonly, serverctrls, clientctrls, timeout, sizelimit)
    except Exception:
        conn_ctxt.__exit__(*sys.exc_info())
        raise
    res = MsgId((conn, msgid))
    weakref.ref(res, functools.partial(conn_ctxt.__exit__, None, None, None))
    return res
