Skip to content

Database Connection

Hartono Halim edited this page Aug 23, 2017 · 2 revisions

Redis

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.

If you're new to Redis, there are few things to pay attention to:

  • Single threaded, mostly.
  • No indexing, join, views, etc.
  • Sorting must be done manually using sorted set. Shift has no built in sorting other than sort by job ID.
  • Some commands can have a huge hit on performance. Don't use KEYS in running production server.
  • Run in trusted server only, Redis has basic authentication and not much else.
  • Read the article on potential latency problems here.

Redis Connection

The Shift connection instance for Redis follows the Azure cache lazy connection pattern. The static connection property in the data layer provides automatic connection pooling and management, please check out the JobDALRedis.cs.

public class JobDALRedis : IJobDAL
{
    private IDatabase _IDatabase;
    private static Lazy<ConnectionMultiplexer> lazyConnection;
    private static ConnectionMultiplexer Connection
    {
        get
        {
            return lazyConnection.Value;
        }
    }

    public IDatabase RedisDatabase
    {
        get
        {
            if (_IDatabase == null)
            {
                Connection.PreserveAsyncOrder = false;
                _IDatabase = Connection.GetDatabase();
            }
            return _IDatabase;
        }
    }

    public JobDALRedis(string connectionString, string encryptionKey)
    {
        if (string.IsNullOrWhiteSpace(connectionString))
            throw new ArgumentNullException("connectionString");

        lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(connectionString));
        this.encryptionKey = encryptionKey;
    }
}

MongoDB Connection

The MongoClient, IMongoDatabase, and IMongoCollection are thread safe. Multiple MongoClient instances will use the same connection pooling when using the same settings. Please see MongoDB references in the Re-Use sections.

Azure DocumentDB Connection

Shift use a static DocumentClient instance to provide a connection to Azure DocumentDB.

public class JobDALDocumentDB : IJobDAL
{
    private const string CollectionID = "Jobs";
    private const string DatabaseID = "ShiftDB";
    private static DocumentClient Client = null; //Best practice to use singleton per application server
    private static Uri CollectionLink;

    private string encryptionKey;

    public JobDALDocumentDB(string connectionString, string encryptionKey, string authKey)
    {
        this.encryptionKey = encryptionKey;

        InitDocumentDB(connectionString, authKey);
    }

    protected void InitDocumentDB(string connectionString, string authKey)
    {
        if(Client == null)
            Client = new DocumentClient(new Uri(connectionString), authKey, new ConnectionPolicy { EnableEndpointDiscovery = false });
        CollectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseID, CollectionID);

        CreateDatabaseIfNotExistsAsync(Client).Wait();
        CreateCollectionIfNotExistsAsync(Client).Wait();
    }
}

Microsoft SQL Server

The Dapper ORM library manages the connection pooling for every SqlConnection attempt.

using (var connection = new SqlConnection(connectionString))
{
    var query = @"INSERT INTO [Job] ([AppID], [UserID], [ProcessID], [JobType], [JobName], [InvokeMeta], 
                [Parameters], [Command], [Status], [Error], [Start], [End], [Created]) 
                VALUES(@AppID, @UserID, @ProcessID, @JobType, @JobName, @InvokeMeta, 
                @Parameters, @Command, @Status, @Error, @Start, @End, @Created);
                SELECT CAST(SCOPE_IDENTITY() as int); ";
    var taskResult = await connection.QueryAsync<string>(query, job);
    job.JobID = taskResult.FirstOrDefault();
}