public SessionPool(int capacity) { // // 为了保证效率,不将_pools分配满,仅保留少于一半的对象作为空槽使用 IICAssert.IsTrue(capacity < 1024 * 1024); _capacity = capacity; _capacityMask = NumberUtils.NextPower2(capacity) * 2; _pools = new object[_capacityMask]; _capacityMask = _capacityMask - 1; }
public int Add(object value) { // // 先增加对象计数,避免容器满 IICAssert.IsNotNull(value); int count = Interlocked.Increment(ref _count); if (count >= _capacity) { Interlocked.Decrement(ref _count); return(-1); } // // 在head后寻找第一个空槽,然后插入对象 int index = -1; do { index = Interlocked.Increment(ref _head) & _capacityMask; } while (Interlocked.CompareExchange(ref _pools[index], value, null) != null); return(index); }
/// <summary> /// 带参数的异步的调用 /// </summary> /// <param name="methodName">方法名</param> /// <typeparam name="TArgs">调用的参数类型</typeparam> /// <param name="args">调用的参数</param> /// <param name="callback">接受回调的delegate</param> public void BeginInvoke <TArgs>(string methodName, TArgs args, Action <RpcClientContext> callback) { IICAssert.IsNotNull(callback); // // 如果Interface声明为强类型检查(默认),则需要判断是否为合法的MethodName和类型 bool isBatch = false; RpcClientMethodSensor method = null; if (_serviceInterface.ClientCheck) { method = _serviceInterface.GetMethod(methodName); if (method == null) { string msg = string.Format("RpcService {0} not exists methods: {1}, please check your code", _serviceInterface.ServiceName, methodName); throw new NotSupportedException(msg); } bool typeChecked = (method.ArgsType == null || method.ArgsType == typeof(RpcNull)) && (typeof(TArgs) == typeof(RpcNull)) || method.ArgsType == typeof(TArgs); if (!typeChecked) { string msg = string.Format("RpcMethod {0}.{1} Expired type<{2}>, not <{3}>", _serviceInterface.ServiceName, methodName, method.ArgsType == null ? "NULL" : ObjectHelper.GetTypeName(method.ArgsType, false), ObjectHelper.GetTypeName(typeof(TArgs), false)); // // TODO: 暂时只记录错误Trace,不抛出异常 // throw new NotSupportedException(msg); _tracing.Error(msg); } if (method.BatchManager != null) { isBatch = true; } } RpcRequest request = new RpcRequest(_serviceInterface.ServiceName, methodName, _contextUri); if (typeof(TArgs) == typeof(RpcNull) || args == null) { request.BodyBuffer = null; } else { request.BodyBuffer = new RpcBodyBuffer <TArgs>(args); } RpcClientTransaction trans; if (isBatch) { _perfCounters.BatchPerSec.Increment(); _perfCounters.BatchTotal.Increment(); _perfCounters.BatchConcurrent.Increment(); trans = method.BatchManager.CreateTransaction(_conn.RemoteUri, request); } else { _perfCounters.InvokeTotal.Increment(); _perfCounters.InvokePerSec.Increment(); _perfCounters.ConcurrentContext.Increment(); trans = _conn.CreateTransaction(request); } RpcClientContext ctx = new RpcClientContext(trans); ctx.SendRequest( delegate(long ticks, RpcClientContext cx2, bool successed) { if (isBatch) { _perfCounters.BatchConcurrent.Decrement(); } else { _perfCounters.ConcurrentContext.Decrement(); } _perfCounters.AvgInvokeElapseMs.IncrementBy(ticks / FrequencyHelper.TicksPerMs); if (!successed) { _perfCounters.InvokeFailed.Increment(); } try { callback(cx2); } catch (Exception ex) { _tracing.Error(ex, "BeginInvoke.Calblack Failed"); } }, _timeout ); }