-
Notifications
You must be signed in to change notification settings - Fork 4
Database Connection
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.
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;
}
}
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.
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();
}
}
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();
}