allow external APIs control over invalidation

Issue #3379 resolved
Mike Bayer repo owner created an issue

so that pool events can be used for clustering and other special cases where we want to invalidate only a subset of connections and have control over whether connections are bumped immediately, or only on next checkout, e.g.:

from sqlalchemy import create_engine
from sqlalchemy import event
import collections
import random

e = create_engine("mysql://scott:tiger@localhost/test")

hosts = ["host1", "host2", "host3"]

conn_recs = collections.defaultdict(set)


@event.listens_for(e, "do_connect")
def do_connect(dialect, conn_rec, carg, cparam):
    host = random.choice(hosts)

    cparam['host'] = host

    conn_rec.info['host'] = host
    conn_recs['host'].add(conn_rec)


@event.listens_for(e, "handle_error")
def handle_error(ctx):
    if ctx.is_disconnect:
        host = ctx.connection.info['host']
        ctx.invalidate_pool_on_disconnect = False
        ctx.connection.invalidate(soft=True)
        for conn_rec in conn_recs[host]:
            conn_rec.invalidate(soft=True)

Comments (3)

  1. Mike Bayer reporter
    • New features added to support engine/pool plugins with advanced functionality. Added a new "soft invalidate" feature to the connection pool at the level of the checked out connection wrapper as well as the :class:._ConnectionRecord. This works similarly to a modern pool invalidation in that connections aren't actively closed, but are recycled only on next checkout; this is essentially a per-connection version of that feature. A new event :class:.PoolEvents.soft_invalidate is added to complement it. fixes #3379

    • Added new flag :attr:.ExceptionContext.invalidate_pool_on_disconnect. Allows an error handler within :meth:.ConnectionEvents.handle_error to maintain a "disconnect" condition, but to handle calling invalidate on individual connections in a specific manner within the event.

    • Added new event :class:.DialectEvents.do_connect, which allows interception / replacement of when the :meth:.Dialect.connect hook is called to create a DBAPI connection. Also added dialect plugin hooks :meth:.Dialect.get_dialect_cls and :meth:.Dialect.engine_created which allow external plugins to add events to existing dialects using entry points. fixes #3355

    → <<cset 0e98795ff2c7>>

  2. Log in to comment