• Ozan Tezcan's avatar
    Reuse temporary client objects for blocked clients by module (#9940) · 6790d848
    Ozan Tezcan authored
    Added a pool for temporary client objects to reuse in module operations.
    By reusing temporary clients, we are avoiding expensive createClient()/freeClient()
    calls and improving performance of RM_BlockClient() and  RM_GetThreadSafeContext() calls. 
    
    This commit contains two optimizations: 
    
    1 - RM_BlockClient() and RM_GetThreadSafeContext() calls create temporary clients and they are freed in
    RM_UnblockClient() and RM_FreeThreadSafeContext() calls respectively. Creating/destroying client object
    takes quite time. To avoid that, added a pool of temporary clients. Pool expands when more clients are needed.
    Also, added a cron function to shrink the pool and free unused clients after some time. Pool starts with zero
    clients in it. It does not have max size and can grow unbounded as we need it. We will keep minimum of 8
    temporary clients in the pool once created. Keeping small amount of clients to avoid client allocation costs
    if temporary clients are required after some idle period.
    
    2 - After unblocking a client (RM_UnblockClient()), one byte is written to pipe to wake up Redis main thread.
    If there are many clients that will be unblocked, each operation requires one write() call which is quite expensive.
    Changed code to avoid subsequent calls if possible. 
    
    There are a few more places that need temporary client objects (e.g RM_Call()). These are now using the same
    temporary client pool to make things more centralized. 
    6790d848
server.h 156 KB