/// <summary> /// 异步等待句柄 /// </summary> /// <param name="transaction">事务</param> /// <param name="timeout">通讯超时处理委托</param> /// <param name="failed">通讯失败处理委托</param> /// <exception cref="System.ArgumentNullException">transaction不能为空</exception> public AsyncWaitingHandle(BusinessMessageTransaction transaction, Action timeout, Action failed) { if (transaction == null) { throw new ArgumentNullException("transaction"); } _transaction = transaction; //begin setup task. TaskCompletionSource <BaseMessage> completionSource = new TaskCompletionSource <BaseMessage>(); Task <BaseMessage> task = completionSource.Task; _transaction.ResponseArrived += delegate(object sender, LightSingleArgEventArgs <BaseMessage> e) { completionSource.SetResult(e.Target); }; _transaction.Timeout += delegate { if (timeout != null) { timeout(); } completionSource.SetException(new CommunicationTimeoutException(string.Format("Transaction: {0} was Timeout!", _transaction.Identity))); }; _transaction.Failed += delegate { if (failed != null) { failed(); } completionSource.SetException(new CommunicationTimeoutException(string.Format("Transaction: {0} was Failed!", _transaction.Identity))); }; _task = task; }
/// <summary> /// 获取部分配置信息 /// </summary> /// <param name="configKey">配置文件KEY名称</param> /// <returns>如果不存在指定条件的配置文件,则返回null</returns> /// <exception cref="ArgumentNullException">参数不能为空</exception> public string GetPartialConfig(string configKey) { if (string.IsNullOrEmpty(configKey)) { throw new ArgumentNullException("configKey"); } #region Get cache first. string config = null; //has cache. if (_configCaches.TryGetValue(configKey, out config)) { return(config); } #endregion PrepareConnection(); #region Get remote config. CSNGetPartialConfigRequestMessage requestMessage = new CSNGetPartialConfigRequestMessage(); requestMessage.Key = configKey; BusinessMessageTransaction transaction = _transactionManager.Create(IdentityHelper.Create((IPEndPoint)_channel.LocalEndPoint), _channel); if (transaction == null) { throw new Exception("Cannot create a CSN message transaction!"); } AutoResetEvent autoResetEvent = new AutoResetEvent(false); transaction.ResponseArrived += delegate(object sender, LightSingleArgEventArgs <BaseMessage> e) { CSNGetPartialConfigResponseMessage rspMsg = (CSNGetPartialConfigResponseMessage)e.Target; if (rspMsg.ErrorId == 0 && !string.IsNullOrEmpty(rspMsg.Config)) { //add cache. _configCaches[configKey] = rspMsg.Config; config = rspMsg.Config; } autoResetEvent.Set(); }; transaction.Failed += delegate { _transactionManager.Remove(transaction.Identity); autoResetEvent.Set(); }; transaction.Timeout += delegate { _transactionManager.Remove(transaction.Identity); autoResetEvent.Set(); }; transaction.SendRequest(requestMessage); //wait 35s. autoResetEvent.WaitOne(35000); autoResetEvent.Dispose(); return(config); #endregion }
/// <summary> /// 创建一个新的消息事务,并将其加入到当前的事务列表中 /// </summary> /// <param name="identity">事务唯一标示</param> /// <param name="channel">消息通信信道</param> /// <param name="timeout">事务超时时间</param> /// <returns>返回一个新的消息事务</returns> /// <exception cref="ArgumentNullException">通信信道不能为空</exception> public BusinessMessageTransaction Create(TransactionIdentity identity, IMessageTransportChannel <BaseMessage> channel, TimeSpan timeout) { if (channel == null) { throw new ArgumentNullException(nameof(channel)); } BusinessMessageTransaction transaction = new BusinessMessageTransaction(new Lease(DateTime.Now.Add(timeout)), channel) { TransactionManager = this, Identity = identity }; return(Add(identity, transaction) ? transaction : null); }
/// <summary> /// 处理一个事务 /// </summary> /// <param name="transaction">消息事务</param> public void Process(BusinessMessageTransaction transaction) { GetAmountByAccountIdRequestMessage reqMsg = (GetAmountByAccountIdRequestMessage)transaction.Request; IExecuteResult executeResult = Global.AuthorizationService.GetAmountByAccountId(reqMsg.AccountId); transaction.SendResponse(executeResult.State != ExecuteResults.Succeed ? new GetAmountByAccountIdResponseMessage { ErrorId = SystemErrors.Unknown, Reason = executeResult.Error } : new GetAmountByAccountIdResponseMessage { Amount = executeResult.GetResult <decimal>() }); }
void NewTransaction(object sender, KJFramework.EventArgs.LightSingleArgEventArgs <IMessageTransaction <BaseMessage> > e) { BusinessMessageTransaction transaction = (BusinessMessageTransaction)e.Target; IMessageProcessor processor; MessageIdentity identity = transaction.Request.MessageIdentity; if (!_processors.TryGetValue(new Protocols { ProtocolId = identity.ProtocolId, ServiceId = identity.ServiceId, DetailsId = identity.DetailsId }, out processor)) { _tracing.Error("#Schedule message failed, because cannot find processor. #P:{0}, S{1}, D{2}", identity.ProtocolId, identity.ServiceId, identity.DetailsId); return; } try { processor.Process(transaction); } catch (Exception ex) { _tracing.Error(ex, null); } }
public void TestMethod1() { //注册processors SystemWorker.Instance.Initialize(ServiceRoles.ABS); //配置数据库连接字符串 Global.DbMySql = new Database(SystemWorker.Instance.ConfigurationProxy.GetField(ServiceRoles.ABS, Global.MySql), Global.CommandTimeOut); Global.DbMySqlReadOnly = new Database(SystemWorker.Instance.ConfigurationProxy.GetField(ServiceRoles.ABS, Global.MySqlReadOnly), Global.CommandTimeOut); Global.DbMySqlAdConversions = new Database( SystemWorker.Instance.ConfigurationProxy.GetField(ServiceRoles.ABS, Global.MySqlAdConversions), Global.CommandTimeOut); Global.DbOaInfoExcutor = new Database(SystemWorker.Instance.ConfigurationProxy.GetField(ServiceRoles.ABS, Global.OaInfoExcutor), Global.CommandTimeOut); BusinessMessageTransaction bs = new BusinessMessageTransaction { }; bs.Request = new GetCampaignByIdRequestMessage { CampaignId = 12023, AccountId = 3659 }; GetCampaignByIdProcessor getAdGroupByIdProcessor = new GetCampaignByIdProcessor(); try { getAdGroupByIdProcessor.Process(bs); } catch { } GetCampaignByIdResponseMessage rspMsg = (GetCampaignByIdResponseMessage)bs.Response; Assert.IsNotNull(rspMsg); }
//new message arrived. void ChannelReceivedMessage(object sender, LightSingleArgEventArgs <System.Collections.Generic.List <BaseMessage> > e) { IMessageTransportChannel <BaseMessage> msgChannel = (IMessageTransportChannel <BaseMessage>)sender; foreach (BaseMessage message in e.Target) { if (message == null) { continue; } _tracing.Info("L: {0}\r\nR: {1}\r\n{2}", msgChannel.LocalEndPoint, msgChannel.RemoteEndPoint, message.ToString()); TransactionIdentity identity; if (message.TransactionIdentity == null) { identity = msgChannel.GenerateRequestIdentity(0U); } else { identity = message.TransactionIdentity; } //response. if (!identity.IsRequest) { _transactionManager.Active(identity, message); continue; } //create transaction by IsOneway flag. IMessageTransaction <BaseMessage> transaction = new BusinessMessageTransaction(_channel) { NeedResponse = !identity.IsOneway, TransactionManager = _transactionManager, Identity = identity, Request = message }; transaction.GetLease().Change(message.ExpireTime); NewTransactionHandler(new LightSingleArgEventArgs <IMessageTransaction <BaseMessage> >(transaction)); } }
/// <summary> /// 为一个事务创建一个异步等待句柄 /// </summary> /// <param name="transaction">等待的事务</param> /// <param name="timeout">通讯超时处理委托</param> /// <param name="failed">通讯失败处理委托</param> /// <returns>返回一个新的异步等待句柄</returns> /// <exception cref="System.ArgumentNullException">transaction参数不能为空</exception> public static IAsyncWaitingHandle <BaseMessage> Create(BusinessMessageTransaction transaction, Action timeout, Action failed) { return(new AsyncWaitingHandle(transaction, timeout, failed)); }
/// <summary> /// 为一个事务创建一个异步等待句柄 /// </summary> /// <param name="transaction">等待的事务</param> /// <returns>返回一个新的异步等待句柄</returns> /// <exception cref="System.ArgumentNullException">transaction参数不能为空</exception> public static IAsyncWaitingHandle <BaseMessage> Create(BusinessMessageTransaction transaction) { return(new AsyncWaitingHandle(transaction, null, null)); }
/// <summary> /// 获取指定表的数据 /// </summary> /// <param name="database">数据库名</param> /// <param name="table">表名</param> /// <param name="hasCache">缓存标识</param> /// <returns>返回表数据</returns> /// <exception cref="ArgumentNullException">参数不能为空</exception> public DataTable GetTable(string database, string table, bool hasCache) { DataTable result = null; Exception exception = null; if (hasCache) { //get cache by default. if ((result = GetCacheTable(string.Format("{0}.{1}", database, table))) != null) { return(result); } } PrepareConnection(); CSNGetDataTableRequestMessage requestMessage = new CSNGetDataTableRequestMessage(); requestMessage.DatabaseName = database; requestMessage.TableName = table; BusinessMessageTransaction transaction = _transactionManager.Create(IdentityHelper.Create((IPEndPoint)_channel.LocalEndPoint), _channel); if (transaction == null) { throw new Exception("Cannot create a CSN message transaction!"); } AutoResetEvent autoResetEvent = new AutoResetEvent(false); transaction.ResponseArrived += delegate(object sender, LightSingleArgEventArgs <BaseMessage> e) { CSNGetDataTableResponseMessage responseMessage = (CSNGetDataTableResponseMessage)e.Target; result = responseMessage.Tables == null ? null : responseMessage.Tables; autoResetEvent.Set(); }; transaction.Failed += delegate { _transactionManager.Remove(transaction.Identity); exception = new Exception("Failed! Cannot get table data config from CSN service, #table: " + table); autoResetEvent.Set(); }; transaction.Timeout += delegate { _transactionManager.Remove(transaction.Identity); exception = new Exception("Timeout! Cannot get table data config from CSN service, #table: " + table); autoResetEvent.Set(); }; transaction.SendRequest(requestMessage); //wait 35s. autoResetEvent.WaitOne(35000); autoResetEvent.Dispose(); if (exception != null) { throw exception; } #region Add table cahce. if (hasCache && result != null) { lock (_lockTablesObj) _cacheTables.Add(string.Format("{0}.{1}", database, table), result); } #endregion return(result); }
/// <summary> /// 获取某个字段的值 /// </summary> /// <typeparam name="T">字段类型</typeparam> /// <param name="database">数据库名</param> /// <param name="table">表名</param> /// <param name="service">服务名称</param> /// <param name="field">字段名</param> /// <returns>返回相应字段的值</returns> /// <exception cref="ArgumentNullException">参数不能为空</exception> public string GetField(string database, string table, string service, string field) { string result = null; #region Get cache first. Dictionary <string, string> items; //has cache. if (_cacheKeys.TryGetValue(service, out items)) { return(items.TryGetValue(field, out result) ? result : null); } #endregion PrepareConnection(); #region Get remote config. Exception exception = null; CSNGetKeyDataRequestMessage requestMessage = new CSNGetKeyDataRequestMessage(); requestMessage.DatabaseName = database; requestMessage.TableName = table; requestMessage.ServiceName = service; BusinessMessageTransaction transaction = _transactionManager.Create(IdentityHelper.Create((IPEndPoint)_channel.LocalEndPoint), _channel); if (transaction == null) { throw new Exception("Cannot create a CSN message transaction!"); } AutoResetEvent autoResetEvent = new AutoResetEvent(false); transaction.ResponseArrived += delegate(object sender, LightSingleArgEventArgs <BaseMessage> e) { CSNGetKeyDataResponseMessage rspMessage = (CSNGetKeyDataResponseMessage)e.Target; #region Add Cache. Dictionary <string, string> values = new Dictionary <string, string>(); if (rspMessage.Items != null) { foreach (KeyValueItem item in rspMessage.Items) { values.Add(item.Key, item.Value); } _cacheKeys.Add(service, values); } //get result. result = values.ContainsKey(field) ? values[field] : null; #endregion autoResetEvent.Set(); }; transaction.Failed += delegate { _transactionManager.Remove(transaction.Identity); exception = new Exception("Failed! Cannot get key data config from CSN service, #key: " + field); autoResetEvent.Set(); }; transaction.Timeout += delegate { _transactionManager.Remove(transaction.Identity); exception = new Exception("Timeout! Cannot get key data config from CSN service, #key: " + field); autoResetEvent.Set(); }; transaction.SendRequest(requestMessage); //wait 35s. autoResetEvent.WaitOne(35000); autoResetEvent.Dispose(); if (exception != null) { throw exception; } #endregion return(result); }