接口详细设计文档 作者:唐为(为哥) 审核:赵锟 日期:2005-5-27 .
接口详细设计说明书
接口详细设计文档 .............................................................................................................................................. 1 1 编写目的 ....................................................................................................................................................... 4 2 名词解释 ....................................................................................................................................................... 4 3 组件分布图 ................................................................................................................................................... 5 4 程序结构 ....................................................................................................................................................... 6
4.1 4.2 4.3 5
接入处理线程类图 ................................................................................................................... 6 接收线程类图 ............................................................................................................................ 7 启动控制图 ................................................................................................................................ 7
程序设计说明 .............................................................................................................................................. 8 5.1 5.2
对原系统的改动 ....................................................................................................................... 8 ThreadInSvcProcessor 接入处理器 ................................................................................... 9 5.2.1 5.2.2 5.2.3 5.2.4 5.3
类图 ..................................................................................................................................... 9 时序图 ............................................................................................................................. 10 流程图 ............................................................................................................................. 10 ThreadInSvcProcessor类说明 ................................................................................. 12
PatternNewSyncAsyncInnerDir 同异步向内处理模式 ........................................... 17 5.3.1 5.3.2 5.3.3 5.3.4
类图 .................................................................................................................................. 17 描述 .................................................................................................................................. 18 流程图 ............................................................................................................................. 18 类说明 ............................................................................................................................. 20
5.4 ThreadReplySvcProcessor 异步应答返回处理器 ...................................................... 25 5.4.1 5.4.2
类图 .................................................................................................................................. 25 类说明 ............................................................................................................................. 25
5.5 ClientInfo 客户端连接数据 ............................................................................................... 34 5.5.1 5.5.2
类图 .................................................................................................................................. 34 类描述 ............................................................................................................................. 34
5.6 ClientInfoTable 客户端连接数据表 ................................................................................ 34 5.6.1 5.6.2
类图 .................................................................................................................................. 34 类描述 ............................................................................................................................. 34
5.7 ClientInfoTableMonitor 客户端连接数据表监控程序 ............................................. 39 5.7.1
类图 .................................................................................................................................. 39
第2页,共45页
接口详细设计说明书
5.7.2 5.8
类说明 ............................................................................................................................. 39
FrontMain 主控程序 ........................................................................................................... 41 5.8.1
5.8.2
类间关系 ......................................................................................................................... 41 流程图 ............................................................................................................................. 42 类说明 ............................................................................................................................. 43
5.8.3 5.9
问题 ........................................................................................................................................... 45
第3页,共45页
接口详细设计说明书
1 编写目的
预期读者:
对接口行为和目的有一定了解的人
背景说明
软件系统名称:接口前端接入服务器
描述 <接口> 接收不同商家的接入,接收数据转发给主机服务器,并同步/异步将
返回数据发给接入商家的行为
2 名词解释
ChannelBase
渠道,通信基类,提供数据收发和释放的方法接口用子类实现来
封装了不同通信方式 目前有TCP短连接接入, 从ACE Message_Queue中读取(IPC MessageQueue-> ACE_Message_Queue)
Trade* trade 商家对象,代表的其实是针对该商家处理方法的集合将接入数据的商
家称为服务商家而将请求面向的商家称为主机商家,主机商家负责同步/异步返回交易的应答数据给接口平台
而接口(数据交换)平台是在两者之间的交换平台
渠道工厂:把接入数据的渠道工厂统一定为服务渠道工厂,发送数据的渠道工厂统一定为主机通道工厂
服务商家 接口平台 主机商家 第4页,共45页
接口详细设计说明书
3 组件分布图 银联 commserver IPC消息队 IPC消息队注 各种服务渠道和主机通道抽ATM commserver 象类都是相同的基类ChannelBase,ATM接入服务器 IPC消息队列 只是作用不同 ATM连接队列 渠道工厂 生成各种渠道 TCP渠TCP渠道 IPC消息队列渠道 列渠道 道 接入服务渠道抽象 代表各种接入服务渠道 接出服务渠道抽象 查不到,丢弃 通知清除超时连接监视器 总控 连接记录表 发送请求线程组 后台服务器 返回应答线程组 接入主机通道抽象 IPC消息队列渠道 接收线程 接收IPC消IPC消息队列 第5页,共45页
接口详细设计说明书
4 程序结构
4.1 接入处理线程类图
ThreadInSvcProcessor是接入处理线程的主流程 收数,接包无误后将处理控制权交给ProcessPattern 是后续处理的全部流程 抽象类 PatternNewSyncAsyncInnerDir 是ProcessPattern的一个子类,实现发送主机服务器并判断同/异步返回 同步直接返回给接入商家
异步只做相应记录
第6页,共45页
接口详细设计说明书
4.2 接收线程类图
4.3 启动控制图
第7页,共45页
接口详细设计说明书
5 程序设计说明
5.1 对原系统的改动
改变原有商家Trade类,不存放渠道对象在商家类中,商家类只执行商家处理,不
负责渠道的管理
改动原有的系统中所有模式的处理,模式处理必须对渠道的释放负责 修改MidHstChannel,添加后台服务需要的2个FML字段,这两个字段是:
第8页,共45页
接口详细设计说明书
FML域名 S_INTERF_NO 描述 接口标识号,整数。系统中接收异步响应程序的唯一编号。用于标识请求的来源,异步应答根据这个号码分发给具体的接口程序。 S_TX_CTRL_ATTR 交易控制属性,字符串。接口都填0,表示这是正常的交易请求。 5.2 ThreadInSvcProcessor 接入处理器
5.2.1 类图
第9页,共45页
接口详细设计说明书
5.2.2 时序图
预先说明:
ChannelBase 渠道通信基类,提供数据收发和释放的方法接口用子类实现来封装了
不同通信方式。目前有 TCP短连接接入。从ACE Message_Queue中读取(IPC MessageQueue-> ACE_Message_Queue)
Trade* trade 商家:代表的其实是针对该商家处理方法的集合 5.2.3 流程图
第10页,共45页
接口详细设计说明书
服务商家 商家渠道工厂 GetChannel No 商家通过渠道收取数据 渠道没取到 退出? Yes Yes 求:执行安全出请错PatternErrorSync应答 丢弃 请求/应答 商家的输入处理 超时? 安全出错? 执行识别出的模式处理 模式 Inner
第11页,共45页
PatternASyncInnerDir 同异步模式PatternNewSyncASyncInnerDir 接口详细设计说明书
5.2.4 ThreadInSvcProcessor类说明
5.2.4.1 功能
收取用不同渠道接入的外部商家的请求识别,解包执行处理的模式具体的流程在模
式中控制,并不做控制 模式可能有3种:
1. 无返回:发送后台,不接收应答对应模式PatternASyncInnerDir,需要修改原来的相关程
序,在本文档中并不涉及
2. 有返回,根据返回的应答判断是同步返回还是异步返回如果接收的应答表明是同步返
回,按正常模式返回如果接收的应答表明是异步返回,按异步模式处理对应模式PatternNewSyncASyncInnerDirThreadInSvcProcessor后续的ProcessPattern 应该是PatternNewSyncASyncInnerDir.ThreadInSvcProcessor只负责接入后调用模式,并处理异常情况
3. 安全异常情况的模式下,调用模式PatternErrorSyncInner来处理,必须限制: 主要的
改动是渠道的释放由模式来管理涉及模式有 PatternASyncInnerDir , PatternNewSyncASyncInnerDir , PatternErrorSyncInner (可能不全面)
5.2.4.2 程序描述 ThreadInSvcProcessor
ThreadInSvcProcessor(Trade* ptrade , SvcChannelFactory* pfactory, bool*_bexit) 功能: 性能:
构造函数
输人项: Trade* trade
接入数据处理的商家类
接入数据渠道工厂
SvcChannelFactory* pfactory bool* exit
退出标志
输出项: 注释:
第12页,共45页
接口详细设计说明书
5.2.4.3 程序描述SvcRun
void SvcRun() 功能: 主控流程
输人项: 无 输出项: 无 流程
:服务商家在开始已经生成,生存周期里一直存在一个DataBus对象(数据总线),每线程一个DataBus对象。在生存周期里一直存在 DataBus对象初始化 循环处理 { } 收尾处理,释放recv_trade SINT32 ret = a_process_loop (Trade* ptrade , SvcChannelFactory* pfactory,DataBus* pDataBus ); if(bool* exit == true ) { } 为下一次使用清空DataBus对象 释放渠道 跳出循环
5.2.4.4 程序描述a_process_loop
SINT32 a_process_loop (Trade* ptrade , SvcChannelFactory* pfactory,DataBus* pDataBus ) 功能:一次交易的处理
输人项: Trade* pTrade , 接收数据的服务商家服务渠道 SvcChannelFactory* pFactory,服务商家接收数据的主机通道 SvcChannelFactory * pFactory 服务商家渠道的生成工厂。 DataBus* pDataBus预先创建的数据总线,不需要每次重建 输出项: S_OK 其他
成功完成
出错信息
第13页,共45页
接口详细设计说明书
流程:
依次执行
GetChannel 生成接入渠道ChannelBase* (根据商家生成一个ChannelBase的子类) 除非出错,整个流程不释放该ChannelBase , 委托给Patten负责释放 TradeRecvData 服务商家接收数据 TradeInProcess服务商家进入处理(最主要一项功能就是接口识别) If( TradeInProcess 成功 && 安全函数出错 ) //安全函数一般是mac校验失败 { 根据p_databus-> pack_type 对请求和应答作2种不同的处理 if( pack_type 是请求 ) { 执行 RequestSecureFailedProcess 函数调用 }else //应答报文 { 结果是应答 直接丢弃,返回成功 不管结果如何都跳到异常处理,但是返回值可能因SecureFailedProcess的执行结果而不同 } }else { 否则生成Patern对象 生成对方商家hst_trade 生成模式对象Pattern,将服务商家和对方商家传入 执行ExecPattern 执行具体的模式处理,将渠道委托给Patten负责释放 }
异常处理:
记录出错信息和时间
当异常发生在ExecPattern之外,释放渠道
(无论异常与否都执行):
结束处理:
释放对方商家 hst_trade 释放模式对象Pattern
为了便于单元测试,从SvcRun中分离出该方法
注释:
也可以在SvcRun中实现上述的全部逻辑
第14页,共45页
接口详细设计说明书
5.2.4.5 程序描述GetChannel
SINT32 GetChannel(SvcChannelFactory* factory, ChannelBase** ACE_Time_Value* time_val ) 功能:调用svc_factory生成服务渠道 性能:
输人项: SvcChannelFactory*
ACE_Time_Value*
svc_factory
渠道工厂
time_val 超时时间这个超时目前是一个固定值,和接收数据
和发送数据的超时无直接联系
ChannelBase* !=NULL 未取得 =NULL 取得 输出项: 返回值
注释:出错信息在该方法中输出流程中只判断是否取得,没有取得则应该跳到开头进入下一次循环
测试:对所有的可能生成的ChannelBase都进行一次测试
5.2.4.6 程序描述TradeRecvData
SINT32 TradeRecvData(Trade* p_recv_trade , ChannelBase* p_chnbase , DataBus* p_databus , ACE_Time_Value* time_out ) 功能: 商家通过渠道接收数据放入p_databus中
收取的渠道
输人项: ChannelBase* p_chnbase
Trade* p_recv_trade DataBus* p_databus
接收的商家 存放数据的DataBus
ACE_Time_Value* time_out 超时时间
输出项: 0 成功
-1 读取失败或者超时
注释:主流程不记录详细出错信息
第15页,共45页
接口详细设计说明书
5.2.4.7 程序描述TradeInProcess
SINT32 TradeInProcess(Trade* p_trade , DataBus* p_databus ) 功能: 中
执行商家的入口处理(识别,解包。。。) p_databus
的_data_buff 和 _len 字段分别表示数据指针和长度
输入处理后将数据填入 p_databus 的 _var_pool 和 _var_reco_pool(识别数据)输人项: Trade* p_ trade
接收服务商家
存放数据的DataBus
DataBus* p_databus
成功
输出项: 0
-1
读取失败或者超时
注释:
没有超时限制,要控制短时间内完成
5.2.4.8 程序描述RequestSecureFailedProcess
SINT32 RequestSecureFailedProcess(DataBus* p_databus , Trade* p_trade , ChannelBase* in_svc_channel) 功能: 对输入是请求报文的安全类函数失败后的处理(输入是应答报文的就直接丢弃)
输人项: DataBus* p_databus数据 Trade* p_trade
输入服务商家
输入服务的渠道
ChannelBase* in_svc_channel 输出项: S_OK
应答保报文,不加理会
INTIDENERROR( SECUFAILED ) 请求报文,执行安全异常处理模式成功 其他。 请求报文,执行安全异常处理模式中出错
注释:无论SecureFailedProcess 的执行结果如何都不继续执行后面的操作
第16页,共45页
接口详细设计说明书
5.2.4.9 程序描述ExecPattern
SINT32 ExecPattern(ProcessPattern * pattern , DataBus* p_databus , ChannelBase* p_channel) 功能: 执行处理模式,全部处理交给pattern
处理模式
输人项: ProcessPattern* pattern
DataBus* p_databus
存放数据的数据总线
ChannelBase* channel 输入服务渠道,交给Pattern管理释放
成功 失败
输出项: S_OK
其他
注释: ChannelBase* 输入渠道,如果Pattern没有生成等错误,还是主控来释放p_channel 执行pattern->Process 后就不管了可能设置一个标志位来表示是否执行了Pattern,执行过最后就不用释放channel了 (是否可以这样?
SINT32 ExecPattern(ProcessPattern * pattern , DataBus* p_databus , ChannelBase** p_channel) 主程序都删除p_channel,但是ExecPattern有可能返回的p_channel 是NULL。此时的主控是什么都不做。如果非null就删除)
5.3 PatternNewSyncAsyncInnerDir 同异步向内
处理模式
5.3.1 类图
第17页,共45页
接口详细设计说明书
5.3.2 描述
预先了解:
交换平台接入的是服务商家,发送的是主机商家(主机)PatternNewSyncAsyncInnerDir 继承 ProcessPattern 类
5.3.3 流程图
见下页
第18页,共45页
接口详细设计说明书
服务商家 出错释 放使用 的通道 出错,记录错误 第19页,共45页 释放!=NULL的渠道 是否服务商家读写渠道接口平台 主机商家 服务商家的读入渠道channel 执行主机商家的输出处理 CallHost 接口平台 tpcall 主机商家 是否同步返回 Yes 通过后台返回的fml变量S_TX_STATUS来判断 创建ClientInfo,记录当前的信服务商家的输出处理(OutProcess),生成输出数据 息。 是否服务商家读写渠道相同 Yes ClientInfo->channel=输入渠道 channel=NULL 后续不释放No ClientInfo.channel=NULL 释放channel channel=NULL Yes write_channel = channel channel=NULL No 释放channel channel = NULL 创建新的write_channel 记录到ClientInfoTable 通过write_channel返回数据释放write_channel 释放!=NULLchannel 的 接口详细设计说明书
5.3.4 类说明
5.3.4.1 构造函数PatternNewSyncAsyncInnerDir
PatternNewSyncAsyncInnerDir(Trade * svc_trade ,Trade *host_trade ); svc_trade 和 host_trade 分别代表服务商家和主机商家
5.3.4.2 方法Process
SINT32 Process(DataBus * p_databus , ChannelBase* p_channel , ACE_Time_Value * time_val) ; DataBus * p_databus 数据总线,包含了解包解开的数据 (FML格式) ChannelBase* p_inchannel 服务商家接入的渠道 ACE_Time_Value * time_val 超时时间
这样我们就拥有了处理需要的全部信息。而其他缺少的是在执行中生成的信息了 服务商家 svc_trade 服务商家 该主机通道和上图的返回渠道可能是不同的路线 接口平台 主机商家 是否生成返回渠道由is_same_rw_channel来判断如果读写渠道相同则使用原来的接入渠道原路返回,不用生成 接入渠道 接口平台 主机商家 host_trade 5.3.4.3 程序描述TradeOutProcess
SINT32 TradeOutProcess( Trade* p_trade , DataBus* p_databus ) 功能: 执行商家输出处理
将数据处理(打包,加密。。。)处理到发送前的状态 输人项: Trade* p_trade 商家
第20页,共45页
接口详细设计说明书
DataBus* p_databus
数据总线
成功 失败
输出项: S_OK
其他
注释:
5.3.4.4 程序描述 CallHost
SINT32 CallHost( Trade* p_hst_trade , DataBus* p_databus ) 输人项: Trade* p_ hst_trade 主机商家 DataBus*
p_databus
数据总线 成功 失败
输出项: S_OK
其他
注释:实际上是封装了一次发送接收的处理在这个模式里并不考虑单发无返回的情况,全部是发送后等待返回的情况
功能:执行和主机商家的一次交互。执行的流程如下:
创建主机商家发送的主机通道, 发送数据 if(读写不是同一条通道) { 释放发送主机通道 设置发送主机通道为NULL 创建主机商家接收的主机通道接收数据 } 释放接收的主机商家通道, 在此过程中所有生成的通讯渠道都要负责清除 失败情况分析:
ChannelBase* send_channel=NULL; ChannelBase* recv_channel =NULL 创建主机商家发送的主机通道 问题:
当tuxedo出错的时候的处理如何进行
回答: 在目前的情况下,主机服务渠道实际上是tpcall后台,
失败
渠道实现中控制了该渠道的发送接收必然返回同步成功,如果通讯失败,由该主机生成返回
第21页,共45页
接口详细设计说明书
码,复制请求数据到返回数据中 {返回码的生成是
设置交易状态为同步返回S_TX_STATUS = 1 , 设置响应码S_RSP_CD 为“2023”
设置响应码描述信息S_RSP_DESC 为“调用后台服务错误” }
交易或者通讯(tpcall)的失败由返回标志位和返回码来确定 可能发生情况: 1. 同步失败 2. 同步成功
可细分为通讯失败和后台处理返回失败(问题中的情况) 同步执行完毕
S_TX_STATUS = 0
3. 异步已发送 异步处理,已经成功发送
5.3.4.5 程序描述TradeInProcess
SINT32 TradeInProcess(Trade* p_trade , DataBus* p_databus ) 功能:
执行主机商家的输入处理
执行主机商家的对应操作,将p_databus中的原始数据识别出接口信息,转换成FML数据存放在p_databus的_var_pool和_var_reco_pool中
输人项: Trade* p_ hst_trade 主机商家
DataBus*
输出项: S_OK
其他
p_databus
数据总线
成功 失败
注释:
5.3.4.6 程序描述is_sync_return
bool is_sync_return(DataBus* p_databus ) 功能: 查看p_databus,判断这次返回是否是同步返回
p_databus
数据总线
输人项: DataBus* 输出项: true
同步返回
第22页,共45页
接口详细设计说明书
false
异步返回
注释: 接入渠道 服务商家 是否生成返回渠道 由is_same_rw_channel来判断 如果读写用相同的渠道返回 接口平台 主机商家 则使用原来的接入渠道,不用生成 5.3.4.7 程序描述is_same_rw_svcchannel
bool is_same_rw_svcchannel ( Trade* p_trade ) 功能:
查看该商家是否在同一链路上返回请求 根据商家查看该商家的服务渠道定义
查询
如果没有定义了商家写的渠道,则表明读写渠道是一样的 如果定义了商家写的渠道,则表明读写渠道是不同的 输人项: Trade* p_trade 输出项: true
false
服务商家 是 不是
注释:
通过查看商家的读写渠道是否相同,可以在处理前明白是否可以提前释放读的渠道
返回给商家的时候明白是否要生成新的写的渠道
5.3.4.8 程序描述createClientInfo
ClientInfo* createClientInfo( DataBus* p_databus , ChannelBase* p_channel ) 功能:
创建一项异步返回的客户端连接记录
无论p_channel是否=NULL,都填入新建的ClientInfo 中
输人项: DataBus* p_databus
第23页,共45页
接口详细设计说明书
ChannelBase* p_channel
返回的渠道
只有读写原路返回的才!=NULL 如果写要重新创建的填NULL
可以的话用ACE_ASSERT判断一下
输出项: ClientInfo*
客户连接记录
!=NULL 成功 =NULL 不大可能
注释:
5.3.4.9 程序描述addToClientInfoTable
void addToClientInfoTable( string key , ClientInfo* info )
功能: 创建一项异步返回的客户端连接记录
键值
目
前
是
由
ClientInfoTable
的
输人项: string key
generateKey(p_databus : DataBus*)生成
ClientInfo* info
记录
输出项: ClientInfo* 注释:
客户连接记录
第24页,共45页
接口详细设计说明书
5.4 ThreadReplySvcProcessor 异步应答返回处理器
5.4.1 类图
5.4.2 类说明
5.4.2.1 程序描述ThreadReplySvcProcessor
ThreadReplySvcProcessor (Trade* ptrade , SvcChannelFactory* pfactory, bool*_bexit) 功能: 性能:
构造函数
输人项: Trade* trade 接口就是ATM服务商家
接收返回数据处理的商家类服务商家,对于ATM
SvcChannelFactory* pfactory bool* exit
接收返回数据渠道工厂
退出标志
输出项: 注释: 接口平台 服务商家 第25页,共45页
异步返回 主机商家 接口详细设计说明书
这里的服务商家就是存放在ClientInfo记录中的商家代码(trade_code)对应的服务商家,要根据trade_code来动态生成和释放
5.4.2.2 程序描述SvcRun
void SvcRun() 主流程 功能:
接收主机商家异步交易返回的数据并向服务商家发送的
输人项: 无 输出项: 无 流程:
生成接收主机商家 DataBus初始化 循环处理 { SINT32 ret = a_process_loop (ptrade , SvcChannelFactory* pfactory,DataBus* pDataBus ); 清空DataBus,以便下次重复使用 if( 退出标志被设置 并且 渠道返回获得渠道收数为超时 ) { } 第26页,共45页
跳出循环 接口详细设计说明书
} 收尾处理,释放recv_trade 注释:
单次处理的方法在a_loop_process中实现
5.4.2.3 程序描述a_process_loop
SINT32 a_process_loop (Trade* ptrade , SvcChannelFactory* pfactory,DataBus* pDataBus ) 功能: 一次交易的处理
将应答数据返回对应的商家(对于ATM接口就是ATMC对应的
输人项: Trade* pTrade 那个)
SvcChannelFactory* pFactory主机商家接收数据的主机通道 异步应答渠道的生成工厂 DataBus* pDataBus 输出项: S_OK
其他
预先创建的数据总线,不需要每次重建
成功完成 出错信息
流程
设置主机商家接收通道和服务商家返回渠道,返回的服务商家为NULL ChannelBase* recvChannel = NULL; ChannelBase* returnChannel = NULL; Trade* svcChannel = NULL; 先执行 GetRecvChannel 取得接收数据的渠道( ChannelBase* ),取不到则直接跳到最后的出错处理 然后执行TradeRecvDataRecvReplyData收数据放入DataBus的_databuff , 长度放入_len 收完数据可以释放recvChannel, recvChannel=NULL 然后执行UnpackRecvData 解开数据 执行UnpackRecvData将数据解开为FML Buffer 然后调用 ClientInfoTable 的 generateKey方法生成键值 然后调用fetchClientInfoRecord取得记录 ClientInfoRecord* 然后RecoverDataBusInfo调用恢复返回前的DataBus信息 然后根据ClientInfoRecord* record 的 trade_code中 调用GetTrade取得要返回信息的服务商家 Trade* 然后调用TradeOutProcess生成对服务商家发送的数据 然后判断是否要生成返回渠道 ChannelBase* return_channel = clientinfo.channel; clientinfo.channel = NULL; if( return_channel = NULL ) { 创建return_channel = CreateOutputChannel… 第27页,共45页
// 释放和clientInfo的联系 接口详细设计说明书
} 调用TradeSendData 向服务商家发送数据,失败转入出错处理 释放return_channel return_channel=NULL 释放svc_trade svc_trade=NULL 出错处理: 记录错误 如果收发渠道 !=NULL 释放收发渠道 如果 svc_trade!=NULL 释放svc_trade 创建失败,转入出错处理 结束处理: 注释:
为了便于单元测试,从SvcRun中分离出该方法
也可以在SvcRun中实现上述的全部逻辑
可以单元测试 正常处理 以及 取渠道超时,输入处理失败,生成服务商家写渠道失败等情况
第28页,共45页
接口详细设计说明书
: ThreadReplySvcProcessor1: GetRecvChannel(Trade*)inFactory : SvcChannelFactorysvc_trade : Trade : ClientInfoTable : ResManager2: GetChannel(ACE_Time_Value *, ChannelBase **, SINT32)3: TradeRecvData(ChannelBase*, Trade*, DataBus*, ACE_Time_Value*)4: RecvData(DataBus *, ACE_Time_Value *)5: UnpackRecvData(DataBus*)6: getInstance( )7: generateKey(DataBus*)8: fetchClientInfoRecord(string)9: fetchRecord(string)10: RecoverDataBusInfo(ClientInfo*, DataBus*)11: getTrade(string)12: GetTrade(const string&, const string&, SINT32, Trade**)13: createhst_trade : Trade14: TradeOutProcess(Trade*, DataBus*)15: OutProcess(DataBus *)write_channel = clientinfo->channel;if ( write_channel==NULL )16: CreateOutputChannel(Trade*)17: TradeSendData(Trade*, DataBus*)18: SendData(DataBus *, ChannelBase*, ACE_Time_Value *) 第29页,共45页
接口详细设计说明书
问题: 是否真的有助于单元测试?
5.4.2.4 程序描述 GetRecvChannel ChannelBase* GetRecvChannel(Trade* p_recv_trade ) 功能: 根据商家取得接收的渠道 接收的商家
输人项: Trade* p_recv_trade 输出项: ChannelBase* !=NULL 取到 =NULL 没有取到 注释:
5.4.2.5 程序描述TradeRecvData (建议改为RecvReplyData)
SINT32 TradeRecvDataRecvReplyData( ChannelBase* p_chnbase , Trade* p_trade , DataBus* p_databus , ACE_Time_Value* p_timeout ) 功能: 从商家收取数据
渠道(定义了数据收取方式)
输人项: ChannelBase* p_chnbase
Trade* p_trade 商家(商家收取数据的格式可能不同) (不可能存在不
同的情况)
DataBus* p_datrabus
数据总线,收取数据存放地
超时时间
ACE_Time_Value* p_timeout
成功 失败
输出项: S_OK
其它
第30页,共45页
接口详细设计说明书
注释:
5.4.2.6 程序描述UnpackRecvData
SINT32 UnpackRecvData (DataBus* p_databus ) 功能: 解开p_databus中的数据(_data_buff,_len),放入_var_pool
输人项: DataBus* p_databus 输出项: S_OK
其它
成功 失败
注释:
5.4.2.7 程序描述fetchClientInfoRecord
ClientInfo* fetchClientInfoRecord(string key) 功能: 从ClientInfoTable中查找客户端连接信息
键值 找到 没找到
输人项: string key 输出项: !=NULL
==NULL
注释:
key是由ClientInfoTable 的generateKey(p_databus : DataBus*)方法生成的
5.4.2.8 程序描述RecoverDataBusInfo
SINT32 RecoverDataBusInfo(ClientInfo* p_clientinfo_record , DataBus* p_databus ) 第31页,共45页
接口详细设计说明书
功能: 从ClientInfo*信息中恢复出原来的DataBus信息
键值 找到 没找到
输人项: string key 输出项: !=NULL
==NULL
注释: 问题:
原来的InProcess以后DataBus的数据怎么办?
这里很容易出错,要单元测试
5.4.2.9 程序描述getTrade Trade* getTrade( string trade_code ) 功能: 生成商家
输人项: string trade_code 输出项: !=NULL ==NULL
找到 没找到 注释:
5.4.2.10 程序描述 TradeOutProcess
SINT32 TradeOutProcess( Trade* p_trade, DataBus* p_databus ) 功能: 执行商家的对外数据处理
输人项: Trade* p_trade DataBus* p_databus
第32页,共45页
接口详细设计说明书
输出项: S_OK
其他
成功 失败
注释:
5.4.2.11 程序描述CreateOutputChannel
ChannelBase* CreateOutputChannel( Trade* out_trade ) 功能: 创建输出的渠道
输人项: Trade* p_trade 输出项: ChannelBase
!=NULL 成功 =NULL 失败
在读写渠道不同的情况下被调用生成写的渠道
注释:
5.4.2.12 程序描述TradeSendData
SINT32 TradeSendData(p_trade : Trade*, p_databus : DataBus*) 功能:
调用商家方法发送数据总线中的数据
输人项: Trade* p_trade
DataBus* p_databus
成功 失败
输出项: S_OK
其他
第33页,共45页
接口详细设计说明书
注释:
5.5 ClientInfo 客户端连接数据
5.5.1 类图
5.5.2 类描述
类描述 存放客户端连接数据和服务渠道数据 成员描述
begin_time
开始放入的时间
timeout_time 预计超时时间(接口处理中有超时时间指定,不过目前基本都没指定) trade_code interface_id pkggrp_id pkg_idx
商家代码 接口编号 报文组号
报文序号
5.6 ClientInfoTable 客户端连接数据表
5.6.1 类图 5.6.2 类描述
功能:
第34页,共45页
接口详细设计说明书
存取客户端ClientInfoTable连接数据 生成存取键值 定时清除超时的记录
5.6.2.1 程序描述getInstance()
ClientInfoTable* getInstance() 功能: 取得ClientInfoTable的单键
输人项:
输出项: ClientInfoTable* 注释:
用double-check加锁
5.6.2.2 程序描述addRecord
SINT32 addRecord( string key , ClientInfo* p_record ) 功能:
添加一条记录到表中
如果已经有了重复的,删除以前的记录,释放记录中的渠道
key
键值
输人项: string
ClientInfo* p_record p_record 记录
成功
输出项: 0
已有项相同主键,但被释放 -1 失败 注释:
加锁
5.6.2.3 程序描述 fetchRecord
ClientInfo* fetchRecord(key : string) : 功能:
取得ClientInfoTable中 key 对应的记录 并从表中去掉和这条记录的联系,防止被清除
第35页,共45页
接口详细设计说明书
输人项: string key 输出项: ClientInfo*
键值
!=NULL 已经找到 ==NULL 没有找到
注释:
如果没有取到,可能已经被清理掉了 加锁
5.6.2.4 程序描述 clearTimeoutRecords
void clearTimeoutRecords() 功能: 查找并清除表中超时的记录
遍历表里的连接记录,如果超时加入待释放的列表 最后遍历释放的列表查看每条待释放的记录 查看记录中的Channel 如果
channel!=NULL
释放channel
删除这条记录 输人项: 输出项:
注释:如果没有取到,可能已经被清理掉了
加锁
要测试删除的使用
主要是锁定的问题。 遍历的时候必须加锁
性能:
而释放渠道就不用加锁
在遍历的情况下加锁,如果需要清除,加入列表中 最后在解锁的情况下对列表中元素进行释放 待释放列表 Lock整张表 循环取下一条记录 第36页,共45页 直到表中记录遍历完为止 接口详细设计说明书
测试
底层使用了ACE_Hash_Map_Manager_Ex 在192.168.100.242 上对1024条记录进行测试 结果如下
插入1024条 < 6毫秒 ( 0.006秒) 遍历1024条 <0.5毫秒
( 0.0005秒)
取出1024条 < 6毫秒 ( 0.006秒)
取出1024条加入删除链表 < 8毫秒 ( 0.008秒) 单次插入 大约 5微秒(0.005毫秒) 单次取出 大约 5微秒(0.005毫秒)
5.6.2.5 程序描述delete_a_client_info
void delete_a_client_info( ClientInfo* tmp_info ) 功能: 删除一条记录,释放占用的渠道
输人项: ClientInfo* tmp_info
第37页,共45页
接口详细设计说明书
输出项: 注释:
是一个内部的函数,是用来删除记录和渠道的工具
不加锁
5.6.2.6 程序描述cleanup
void cleanup () 功能: 清空全部记录,释放占用的渠道
输人项: 输出项: 注释:
加锁
5.6.2.7 程序描述generateKey
string generateKey(DataBus* p_databus ) 功能: 从p_databus取相应字段生成键值
输人项: DataBus* p_databus 数据总线
输出项: string key
生成的键值
注释:
第38页,共45页
接口详细设计说明书
5.7 ClientInfoTableMonitor 客户端连接数据表监控
程序
5.7.1 类图 5.7.2 类说明
功能:
存取客户端ClientInfoTable连接数据 生成存取键值 定时清除超时的记录 成员:
ACE_Thread_t thread_id ClientInfoTable* p_table int interval_seconds
5.7.2.1 程序描述ClientInfoTableMonitor
ClientInfoTableMonitor(ClientInfoTable* p_table , int interval_seconds ) 功能: 构造函数,锁定目标Monitor,和时间间隔
输人项: ClientInfoTable* p_table 目标表 int interval 输出项: 注释:
间隔秒数
第39页,共45页
接口详细设计说明书
5.7.2.2 程序描述startup
int startup() 功能: 启动监视线程
输人项: 输出项: 0
启动成功
-1 启动不成功
注释:
5.7.2.3 程序描述notify_cleanup
void notify_cleanup() 功能: 通知ClientInfoTable做一次超时记录的清理
输人项: 输出项: 注释:
5.7.2.4 程序描述shutdown
void shutdown() 功能:
关闭监视线程
等待线程关闭后返回(join)
输人项: 输出项: 注释:
第40页,共45页
接口详细设计说明书
5.8 FrontMain 主控程序
5.8.1 类间关系
第41页,共45页
接口详细设计说明书
5.8.2 流程图
建立接受应答商家对象 启动命令接收器,接受命令,等待退出 第42页,共45页
系统环境初始化操作(InitEnv) 建立服务商家对象 建立服务商家接入渠道工厂 建立接收应答商家接入渠道工厂 创建服务商家处理线程组 创建应答处理线程组 从这里开始接入服务处理 服务商家接入渠道初始化 接收应答商家接入渠道初始化 ClientInfoTableMonitor开始监控 接口详细设计说明书
5.8.3 类说明
功能
启动和关闭整个系统
ThreadInSvcProcessor和ThreadReplySvcProcessor都传递给InteTask模板生成
说明:
线程组全部采用赵锟原来的体系结构,使用InterTask Template
只是有一点改动,factory的Initialize最后再做保证 ThreadInSvcProcessor 和 ThreadReplySvcProcessor 2个线程执行函数 构造函数类型为
T( Trade* ptrade , SvcChannelFactory* pfactory, bool*_bexit ); 循环执行函数名为 void SvcRun();
即可使用赵锟原来的体系结构
5.8.3.1 程序描述 FrontMain
FrontMain( const string& in_trade_code , const string& reply_trade_code ) 功能: 构造FrontMain
接入请求的商家
异步回复的商家
输人项: const string& in_trade_code
const string& reply_trade_code
启动成功
输出项: 0
-1 启动失败
注释:
5.8.3.2 程序描述InitEnv
SINT32 InitEnv () 功能: 系统环境初始化操作,
打开数据库 DbOpen() 装载factory.so
第43页,共45页
接口详细设计说明书
转载libpackagefactory.so 输人项:
输出项: ==0 启动成功就不返回了,直到执行shutdown或者core dump退出
!=0 启动失败,退出
注释:
5.8.3.3 程序描述 startup
SINT32 startup() 功能: 启动整个系统
输人项: 输出项:
==0 启动成功就不返回了,直到执行shutdown或者core dump退出 !=0 启动失败,退出 启动顺序
注释:
1. InitEnv ,失败直接退出
2. 将目前MainApp.cpp中InitSvcChannel中访问数据库,打开factory.so的代码放入这个方
法
3. 构造接入和返回数据的ChannelFactory 4. 启动2个线程组 new InteTask<>-> Start ();
5. 2个SvcChannellFactory.Initialize初始化,这样能接入请求和异步返回数据 6. 启动ClientInfoTableMonitor开始监控连接超时 7. 创建命令接收对象, 等待下一步命令
5.8.3.4 程序描述shutdown
void shutdown() 功能: 关闭系统
输人项: 输出项: 注释:
依次关闭
第44页,共45页
接口详细设计说明书
factory1 关闭(最好能清空)
线程组1 接收请求发送线程组,线程执行到队列为空,然后退出 factory2 关闭(最好能清空)
线程组2 返回应答线程组,线程执行到队列为空,然后退出 ClientInfoTableMonitor 关闭 ClientInfoTable
清空
命令接收对象自动删除(删除时清除接收命令的消息队列)
5.9 问题
1. 多个类ThreadInSvcProcessor, PatternNewSyncAsyncInnerDir, ThreadReplySvcProcessor
中都重复定义了TradeOutProcess, TradeInProcess等方法,是否有好的方法合并 2. ATM等超时时间的设置问题,在渠道上设置还是在接口设置 3. 多个服务渠道的情况下,如何知道使用的是哪一条 4. 如何等待2个线程组执行队列为空
第45页,共45页
因篇幅问题不能全部显示,请点此查看更多更全内容