关于midas的RemoteDataModule(200分)

  • 主题发起人 主题发起人 semual
  • 开始时间 开始时间
S

semual

Unregistered / Unconfirmed
GUEST, unregistred user!
[?]
数据库应用,业务中间层使用midas实现,内部处理过程包含一定的负载均衡机制
midas模块的tlb文件主要部分如下:
interface

uses ActiveX, Classes, Graphics, Midas, StdVCL, Variants, Windows;



// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
ServerMajorVersion = 1;
ServerMinorVersion = 0;

LIBID_Server: TGUID = '{0CE99800-9F28-11D1-8944-00A0248E5091}';

IID_INMSRDM: TGUID = '{0CE99801-9F28-11D1-8944-00A0248E5091}';
CLASS_NMSRDM: TGUID = '{0CE99802-9F28-11D1-8944-00A0248E5091}';
CLASS_Pooler: TGUID = '{0CE99804-9F28-11D1-8944-00A0248E5091}';//用于负载均衡

type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
INMSRDM = interface;
INMSRDMDisp = dispinterface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
NMSRDM = INMSRDM;
Pooler = INMSRDM;


// *********************************************************************//
// Interface: INMSRDM
// Flags: (4432) Hidden Dual OleAutomation Dispatchable
// GUID: {0CE99801-9F28-11D1-8944-00A0248E5091}
// *********************************************************************//
INMSRDM = interface(IAppServer)
['{0CE99801-9F28-11D1-8944-00A0248E5091}']
procedure InsertTask(out ErrorCode: OleVariant; ne_instance_id: OleVariant;
out map_obj_id: OleVariant; out map_parent_obj_id: OleVariant;
out ne_parent_id: OleVariant); safecall;
end;
INMSRDMDisp = dispinterface
['{0CE99801-9F28-11D1-8944-00A0248E5091}']
procedure InsertTask(out ErrorCode: OleVariant; ne_instance_id: OleVariant;
out map_obj_id: OleVariant; out map_parent_obj_id: OleVariant;
out ne_parent_id: OleVariant); dispid 1;
end;

CoNMSRDM = class
class function Create: INMSRDM;
class function CreateRemote(const MachineName: string): INMSRDM;
end;

// *********************************************************************//
// The Class CoPooler provides a Create and CreateRemote method to
// create instances of the default interface INMSRDM exposed by
// the CoClass Pooler. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoPooler = class
class function Create: INMSRDM;
class function CreateRemote(const MachineName: string): INMSRDM;
end;

implementation

uses ComObj;

class function CoNMSRDM.Create: INMSRDM;
begin
Result := CreateComObject(CLASS_NMSRDM) as INMSRDM;
end;

class function CoNMSRDM.CreateRemote(const MachineName: string): INMSRDM;
begin
Result := CreateRemoteComObject(MachineName, CLASS_NMSRDM) as INMSRDM;
end;

class function CoPooler.Create: INMSRDM;
begin
Result := CreateComObject(CLASS_Pooler) as INMSRDM;
end;

class function CoPooler.CreateRemote(const MachineName: string): INMSRDM;
begin
Result := CreateRemoteComObject(MachineName, CLASS_Pooler) as INMSRDM;
end;

end.

实际上,程序内部实现了两个都继承INMSRDM接口的RemoteDataModule,其中一个负责负载均衡,
一个负责实际的业务处理,在业务处理RemoteDataModule内
首先声明全局变量 RDMFactory
然后在RemoteDataModuled的initialization节中得到该com工厂
initialization
RDMFactory := TComponentFactory.Create(ComServer, TNMSRDM,
Class_NMSRDM, ciInternal, tmApartment);

然后在负载均衡RemoteDataModule中,定义一个缓冲池,缓冲池内可放最大数量为max的
业务处理RemoteDataModuled。
1、用户请求到达时,从缓冲池内获得可用的RemoteDataModuled
var
Intf: INMSRDM;
1)若缓冲池内RemoteDataModuled的数量不到max,那么按照以下方式生成
业务处理RemoteDataModuled:
Intf := RDMFactory.CreateComObject(nil) as INMSRDM;
然后将该RemoteDataModuled放入缓冲池,并标记为已用
2)若缓冲池内RemoteDataModuled的数量达到max,则等待可用的RemoteDataModuled;
2、得到Intf后,将调用转发给Intf。
3、将该Intf标记为可用
4、返回结果

用户调用的是负载均衡RemoteDataModule。

在业务处理RemoteDataModule中,使用了同事用vc开发的com组件,通过import type library
加载到工程中,生成了xxx_tlb.pas文件,该com组件未实现IDispatcher接口,
在InsertTask中用
CreateComObject(CLASS_SnmpCOM) as ISnmpRowGet;
来获得该com组件的某个接口,此时出现异常EIntfCastError,异常信息是接口不支持,即
类型信息不知。
但是如果使用标准的com组件,比如通过import m$的word,生成了word_tlb.pas,然后此处
使用组件内的WordApplication接口,就可以成功,能够自动启动word并打开一个新文档。
我的问题是:
究竟是同事开发的com组件没有实现自动委派接口造成的,还是我的线程模式不符合该组件所
需要的free模式,或者哪位犇人原来做过这方面的工作,还望告知一二,我都被这个异常折腾两天
了,就剩这点东西调不通,不然就可以交活结帐了,多谢多谢!!!
//bow
//thanks





 
学习学习
 
后退
顶部