PageRenderTime 61ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/NetCassa/Apache.Cassandra.Client/CassandraConnectionFactory.cs

http://netcassa.codeplex.com
C# | 163 lines | 127 code | 32 blank | 4 comment | 29 complexity | 9bb70e9d26278c7e1d2085ad2630c56c MD5 | raw file
  1. namespace Apache.Cassandra.Client {
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Net;
  6. using System.Reflection;
  7. using Apache.Cassandra.Client.Diagnostics;
  8. using Thrift.Protocol;
  9. using Thrift.Transport;
  10. internal class CassandraConnectionFactory {
  11. internal static readonly string PerformanceCountersInstanceName = GetPerformanceCountersInstanceName();
  12. private IDictionary<object, CassandraConnectionPool> pools;
  13. private CassandraClientFactoryCounters performanceCounters;
  14. private CassandraConnectionFactory() {
  15. pools = new Dictionary<object, CassandraConnectionPool>();
  16. performanceCounters = new CassandraClientFactoryCounters(PerformanceCountersInstanceName);
  17. }
  18. private static readonly CassandraConnectionFactory singleton = new CassandraConnectionFactory();
  19. public static CassandraConnectionFactory Factory {
  20. get {
  21. return CassandraConnectionFactory.singleton;
  22. }
  23. }
  24. internal CassandraClientFactoryCounters PerformanceCounters {
  25. get {
  26. return performanceCounters;
  27. }
  28. }
  29. internal CassandraInternalConnection GetConnection(CassandraConnection owner) {
  30. Debug.Assert(null != owner);
  31. CassandraInternalConnection connection;
  32. CassandraConnectionPool pool = GetClusterPool(owner);
  33. if (null == pool) {
  34. CassandraConnectionString options = owner.Options;
  35. connection = CreateConnection(null, options);
  36. if (null == connection) {
  37. throw new InvalidOperationException();
  38. }
  39. CassandraConnectionFactory.Factory.PerformanceCounters.HardConnectsPerSecond.Increment();
  40. connection.MakeNonPooledConnection(owner);
  41. CassandraConnectionFactory.Factory.PerformanceCounters.NumberOfNonPooledConnections.Increment();
  42. } else {
  43. connection = pool.PopConnection(owner);
  44. }
  45. if (null == connection) {
  46. // TODO: Unable to connect
  47. throw new Exception();
  48. }
  49. return connection;
  50. }
  51. private CassandraConnectionPool GetClusterPool(CassandraConnection connection) {
  52. Debug.Assert(null != connection);
  53. Debug.Assert(null != connection.Options);
  54. CassandraConnectionString options = connection.Options;
  55. if (!options.Pooling) {
  56. return null;
  57. }
  58. object connectionString = options.ConnectionString;
  59. Debug.Assert(null != connectionString);
  60. CassandraConnectionPool pool;
  61. if (!pools.TryGetValue(connectionString, out pool)) {
  62. lock (pools) {
  63. if (!pools.TryGetValue(connectionString, out pool)) {
  64. IDictionary<object, CassandraConnectionPool> newpools = new Dictionary<object, CassandraConnectionPool>(pools.Count + 1);
  65. foreach (var i in pools) {
  66. newpools.Add(i);
  67. }
  68. pool = new CassandraConnectionPool(options);
  69. pool.Startup();
  70. newpools.Add(connectionString, pool);
  71. pools = newpools;
  72. PerformanceCounters.NumberOfActiveConnectionPools.Increment();
  73. }
  74. }
  75. }
  76. return pool;
  77. }
  78. internal CassandraInternalConnection CreateConnection(CassandraConnectionPool pool, CassandraConnectionString options) {
  79. EndPoint endpoint = new DnsEndPoint(options.Server, options.Port);
  80. return CreateConnection(pool, endpoint, options);
  81. }
  82. internal CassandraInternalConnection CreateConnection(CassandraConnectionPool pool, EndPoint endpoint, CassandraConnectionString options) {
  83. TTransport transport = CreateTransport(endpoint);
  84. if (null == transport) {
  85. return null;
  86. }
  87. TProtocol protocol = CreateProtocol(transport);
  88. if (null == protocol) {
  89. return null;
  90. }
  91. Cassandra.Client client = new Cassandra.Client(protocol);
  92. return new CassandraInternalConnection(client, endpoint, options);
  93. }
  94. private TTransport CreateTransport(EndPoint endpoint) {
  95. IPEndPoint ip = endpoint as IPEndPoint;
  96. DnsEndPoint dns = null == ip ? endpoint as DnsEndPoint : new DnsEndPoint(ip.Address.ToString(), ip.Port);
  97. if (null == dns) {
  98. return null;
  99. }
  100. TSocket socket = new TSocket(dns.Host, dns.Port);
  101. socket.TcpClient.NoDelay = true;
  102. return new TFramedTransport(socket);
  103. }
  104. private TProtocol CreateProtocol(TTransport transport) {
  105. return new TBinaryProtocol(transport);
  106. }
  107. static private string GetPerformanceCountersInstanceName() {
  108. // Get process name
  109. string processName = null;
  110. Assembly assembly = Assembly.GetEntryAssembly();
  111. if (null != assembly) {
  112. AssemblyName name = assembly.GetName();
  113. if (null != name) {
  114. processName = name.Name;
  115. }
  116. }
  117. if (null == processName) {
  118. AppDomain appDomain = AppDomain.CurrentDomain;
  119. if (null != appDomain) {
  120. processName = appDomain.FriendlyName;
  121. }
  122. }
  123. // Get process id
  124. int pid = SafeNativeMethods.GetCurrentProcessId();
  125. // Create instance name
  126. string instanceName = String.Format((IFormatProvider)null, "{0}[{1}]", processName, pid);
  127. instanceName = instanceName.Replace('(','[').Replace(')',']').Replace('#','_').Replace('/','_').Replace('\\','_');
  128. return instanceName;
  129. }
  130. }
  131. }