Skip to content

Handle ConnectionLost errors in txredis.client.RedisClient.connectionLost() #53

@isislovecruft

Description

@isislovecruft

There is a problem where, after a txredis.client.RedisClient has successfully sent a QUIT command to the Redis server, the server properly tears down the connection, and Twisted properly calls txredis.client.RedisClient.connectionLost, which calls txredis.RedisClient.failRequests, the later of which propagates the twisted.internet.error.ConnectionLost to all requests in its internal queue (txredis.RedisClient._request_queue), without seemingly bothering to check if these requests have already succeeded. This causes the deferred transactions in the internal queue to assume that their overarching RedisClient has a half-terminated TCP connection, causing thousands of errbacks to get propagated for no good reason.

Technically, the ConnectionLost is not really an error, it's just a signal sent from Twisted that the other end tore down the connection. This is precisely what is supposed to happen when you send QUIT, so this is somewhat a design flaw in txredis.

For a piece of software I develop at work, I have fixed this issue by subclassing RedisClient and overriding the connectionLost method as follows:

class MyRedisClient(txredis.client.RedisClient):
    def connectionLost(self, reason):
        trapped = reason.trap(ConnectionLost)
        if trapped:
            log.msg(
                ("Trap prevented ConnectionLost from propagating to "
                 "`RedisClient.failRequests()`. All's well."))
        else:
            super(MyRedisClient, self).connectionLost(reason)

If desired, I can gladly either fork or provide git patches, if you think that this issue merits fixing.

Thanks for creating txredis!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions