1
votes

I want to initiate the Redis connection as a background task, so that the user need not await for the Redis connection to get established. If Redis connection is not setup or if Redis is unavailable then data shall be fetched from the source, without impacting the user.

The application is an AWS Lambda Web API project. I want to avoid connection delays in individual requests but I don't want to increase the cold startup time by waiting to connect at startup either.

I'm using the StackExchange Redis Client library.

In order to accomplish this, I want to initiate the Redis connection in background task.

1
This is far too vague - for what kind of application? What does the user need not await for the Redis connection to get established mean? For desktop apps, it means the UI doesn't freeze. Web apps don't freeze while waiting. And what does in thread safe manner mean for your code? If you don't modify global state, there's no risk, and a simple await myClient.ConnectAsync() would do, assuming your Redis library has async methodsPanagiotis Kanavos
And none of those things has to do with thread safety or freezing. you're asking for caching with fallback. Which has nothing to do with threads, and ... is probably already implemented, at least partially, through the distributed caching middlewarePanagiotis Kanavos
This is a case of the XY Problem. You have a problem X (how to use Redis with fallback to another source) and assumed that Y is the solution (background threads), so when things don't work, you ask about Y. But in this case Y has nothing to do with XPanagiotis Kanavos
@Shaheer ********you still have to wait if you do that********. Anyway, post your real code.Panagiotis Kanavos
There's no reason to. It's not that people don't understand your problem. You're asking about the wrong problem. If you want to test the connection do it at startup. Subsequent connections won't take that long. Add a Redis health check if you want to. If you suspect the connection will go down, write your code so it falls back to the database or whatever other source you have.Panagiotis Kanavos

1 Answers

2
votes

There's no need for extra background tasks. The StackExchange.Redis library allows asynchronous connections with ConnectionMultiplexer.ConnectAsync. What's needed is a way to check if that connection is complete and if not, use another source.

One way to do this is to wrap data access in a service that opens the connection asynchronously in its constructor. Its methods can check whether the connection is open and either use Redis or a fallback source (eg a database) if not.

class MyFallbackService
{
    Task<ConnectionMultiplexer> _redisTask;

    public MyFallbackService(string redisConf,string conString)
    {
        _redisTask = ConnectionMultiplexer.ConnectAsync(redisConf);
        ...
    }

    public async Task<string> GetValue(string key)
    {
        if (_redisTask.IsCompleted)
        {
            var redis=_redisTask.Result;
            var db=redis.GetDatabase(...);
            var value= await db.StringGetAsync(key);
        }
        else
        {
            //Use the fallback source
        }
    }
}

This service can be created and registered as a Singleton instance in Startup.ConfigureServices. This way the connection process will begin at at startup but won't block the startup process :

services.AddSingleton(new MyFallbackService(...));