Created
December 13, 2012 16:22
-
-
Save AndrewLane/4277602 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8" ?> | |
<configuration> | |
<configSections> | |
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/> | |
<section name="awsmemcachedbucket" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" /> | |
<section name="awsmembaseBucketUsingMemcachedClient" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" /> | |
<section name="awsmembaseBucket" type="Couchbase.Configuration.CouchbaseClientSection, Couchbase" /> | |
</configSections> | |
<appSettings> | |
<add key="numberOfKeys" value="10"/> | |
<add key="cacheKeyPrefix" value="cachekey"/> | |
<add key="cacheKeyTimeToLiveMinutes" value="1"/> | |
<add key="secondsToSleepBetweenIterations" value="5"/> | |
<add key="useCouchbaseClient" value="true" /> | |
<add key="configSectionName" value="awsmembaseBucket" /> | |
</appSettings> | |
<awsmemcachedbucket protocol="Binary"> | |
<servers> | |
<add address="server1.redactedforsecurity.com" port="11299" /> | |
<add address="server2.redactedforsecurity.com" port="11299" /> | |
<add address="server3.redactedforsecurity.com" port="11299" /> | |
</servers> | |
<socketPool minPoolSize="10" maxPoolSize="20" connectionTimeout="00:00:00.250" deadTimeout="00:00:10" queueTimeout="00:00:00.250" /> | |
<!-- | |
<locator type="CacheReplicationAndFailoverTester.DumbNodeLocator, CacheReplicationAndFailoverTester" /> | |
--> | |
</awsmemcachedbucket> | |
<awsmembaseBucketUsingMemcachedClient protocol="Binary"> | |
<servers> | |
<add address="server1.redactedforsecurity.com" port="11297" /> | |
<add address="server2.redactedforsecurity.com" port="11297" /> | |
<add address="server3.redactedforsecurity.com" port="11297" /> | |
</servers> | |
<socketPool minPoolSize="10" maxPoolSize="20" connectionTimeout="00:00:00.250" deadTimeout="00:00:10" queueTimeout="00:00:00.250" /> | |
</awsmembaseBucketUsingMemcachedClient> | |
<awsmembaseBucket> | |
<servers bucket="membasebucket" bucketPassword="" retryCount="0" retryTimeout="00:00:00.500"> | |
<add uri="http://server1.redactedforsecurity.com:8091/pools" /> | |
<add uri="http://server2.redactedforsecurity.com:8091/pools" /> | |
<add uri="http://server3.redactedforsecurity.com:8091/pools" /> | |
</servers> | |
<!-- note: had to bump connectionTimeout to 3 full seconds --> | |
<socketPool minPoolSize="10" maxPoolSize="20" connectionTimeout="00:00:03.00" deadTimeout="00:00:10" queueTimeout="00:00:00.250" /> | |
</awsmembaseBucket> | |
<log4net> | |
</log4net> | |
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Configuration; | |
using System.Linq; | |
using System.Threading; | |
using Couchbase; | |
using Couchbase.Configuration; | |
using Enyim.Caching; | |
using Enyim.Caching.Configuration; | |
using Enyim.Caching.Memcached; | |
namespace CacheReplicationAndFailoverTester | |
{ | |
class CacheReplicationAndFailoverTester | |
{ | |
private const string CacheMissIndication = "X"; | |
private const string CacheHitIndication = "_"; | |
private const string UncaughtExceptionIndication = "E"; | |
private const string StoreFailureIndication = "F"; | |
private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(CacheReplicationAndFailoverTester)); | |
private static CouchbaseClient _couchbaseClient; | |
private static IMemcachedClient _enyimClient; | |
private static readonly bool UseCouchbaseClient = Convert.ToBoolean(ConfigurationManager.AppSettings["useCouchbaseClient"]); | |
private static readonly int NumberOfKeys = Convert.ToInt32(ConfigurationManager.AppSettings["numberOfKeys"]); | |
private static readonly string CacheKeyPrefix = ConfigurationManager.AppSettings["cacheKeyPrefix"]; | |
private static readonly int CacheKeyTimeToLiveMinutes = Convert.ToInt32(ConfigurationManager.AppSettings["cacheKeyTimeToLiveMinutes"]); | |
private static readonly int SecondsToSleepBetweenIterations = Convert.ToInt32(ConfigurationManager.AppSettings["secondsToSleepBetweenIterations"]); | |
private static readonly string ConfigSectionName = ConfigurationManager.AppSettings["configSectionName"]; | |
private static readonly TimeSpan TtlOfKeys = new TimeSpan(days: 0, hours: 0, minutes: CacheKeyTimeToLiveMinutes, seconds: 0); | |
static void Main() | |
{ | |
LogManager.AssignFactory(new Log4NetFactory()); | |
Console.WriteLine("Starting test. There will be {0} keys in use and they will have a TTL of {1} minute(s).", NumberOfKeys, CacheKeyTimeToLiveMinutes); | |
Console.WriteLine("Will sleep {0} second(s) between iterations.", SecondsToSleepBetweenIterations); | |
Console.WriteLine("{0} signifies a cache miss followed by a successful set.", CacheMissIndication); | |
Console.WriteLine("{0} signifies a cache hit.", CacheHitIndication); | |
Console.WriteLine("{0} signifies an uncaught exception.", UncaughtExceptionIndication); | |
Console.WriteLine("{0} signifies a cache miss followed by a FAILURE setting new data.", StoreFailureIndication); | |
InitializeClient(); | |
while (true) | |
{ | |
var misses = 0; | |
for (int i = 0; i < NumberOfKeys; i++) | |
{ | |
try | |
{ | |
string cacheKey = GetCacheKey(CacheKeyPrefix, i); | |
var data = PerformGet(cacheKey); | |
if (String.IsNullOrWhiteSpace(data) == false) | |
{ | |
Console.Write(CacheHitIndication); | |
} | |
else | |
{ | |
misses++; | |
Console.Write(PerformSet(cacheKey, GetCacheKeyValue(i)) ? CacheMissIndication : StoreFailureIndication); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Console.Write(UncaughtExceptionIndication); | |
Logger.Error("Uncaught exception", ex); | |
} | |
} | |
//spit out stats for this iteration of the loop | |
Console.WriteLine(" {0} {1}/{2} misses", DateTime.Now.ToString("HH:mm:ss"), misses, NumberOfKeys); | |
//sleep for a while and start it all over | |
Thread.Sleep(millisecondsTimeout: SecondsToSleepBetweenIterations * 1000); | |
} | |
} | |
/// <summary> | |
/// set up our client to talk to the cache | |
/// </summary> | |
static void InitializeClient() | |
{ | |
if (UseCouchbaseClient) | |
{ | |
var section = (ICouchbaseClientConfiguration)ConfigurationManager.GetSection(ConfigSectionName); | |
if (section == null || section.Urls.Count <= 0) | |
throw new ConfigurationErrorsException( | |
"Cannot create CouchbaseClient. Got a default section with 0 URLs when trying the .config file"); | |
Console.WriteLine("Couchbase REST URLs are: {0}", String.Join(", ", section.Urls)); | |
_couchbaseClient = new CouchbaseClient(section); | |
} | |
else | |
{ | |
var section = (MemcachedClientSection)ConfigurationManager.GetSection(ConfigSectionName); | |
if (section == null || section.Servers.Count <= 0) | |
{ | |
throw new ConfigurationErrorsException("Got a default section with 0 servers when trying the .config file"); | |
} | |
Console.WriteLine("Couchbase Servers are: {0}", | |
String.Join(", ", | |
section.Servers.ToIPEndPointCollection() | |
.Select(item => String.Format("{0}:{1}", item.Address, item.Port)))); | |
_enyimClient = new MemcachedClient(section); | |
} | |
} | |
/// <summary> | |
/// Get a cache key string based on the index | |
/// </summary> | |
static string GetCacheKey(string keyPrefix, int index) | |
{ | |
return String.Format("{0}_{1}", keyPrefix, index); | |
} | |
/// <summary> | |
/// Get a value to put in the cache for the particular index | |
/// </summary> | |
static string GetCacheKeyValue(int index) | |
{ | |
return String.Format("value_{0}_{1}", index, DateTime.Now.ToString("HH:mm:ss")); | |
} | |
/// <summary> | |
/// Try a get data from the cache | |
/// </summary> | |
static string PerformGet(string cacheKey) | |
{ | |
return UseCouchbaseClient ? _couchbaseClient.Get<string>(cacheKey) : _enyimClient.Get<string>(cacheKey); | |
} | |
/// <summary> | |
/// Try to stuff data in the cache and return a flag whether it succeeded or not | |
/// </summary> | |
private static bool PerformSet(string cacheKey, string newData) | |
{ | |
return UseCouchbaseClient | |
? _couchbaseClient.Store(StoreMode.Set, cacheKey, newData, TtlOfKeys) | |
: _enyimClient.Store(StoreMode.Set, cacheKey, newData, TtlOfKeys); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment