Remoting Discussion(二)
其具体思路:
1.对象的创建
我们首先要在用户创建对象时套上代理,所以我们需要提供一个创建对象的工厂,由该工厂创建出的远程对象都将受代理的控制:

那么用户每次创建时都会有三个对象产生:

Question:
因为需要用到System.Activator来创建远程对象的本地实例,所以需要在本地部署有远程对象,那么如果远程对象没有部署到客户端,而只部署了远程对象所实现的接口在客户端,那么我们无法在client用System.Activator创建一个远程对象的本地实例,从而无法给它套上真实代理并获取透明代理。Solution:
通过接口我们可以获取Method的信息,然后用Emit在运行时构建远程对象的Mock。
2.RealProxy的实现
通过Remoting Infrastructure来实现一个AOP的框架。
在Remoting Infrastructure中,通过RealProxy我们可以拦截到对方法的调用,那么拦截到后我们需要将该调用重定向到Remote Server上的远程对象上,而在这个重定向的过程中我们可以使用Retry Router的机制。
为了灵活和可扩充性,我们在自己的RealProxy里实现一个责任链(Chain of Responsibility),将对方法调用的消息通过责任链最后传给Proxied Local Object。这样我们可以在责任链上插入任意个的消息拦截处理器。
这样我们实现一个Retry Route的Handler插入到责任链上。
3.Retry Route的Handler的实现
在该Handler中,我们会将方法调用的Message拦截下来,获取对象的信息和所调用的方法的信息,然后根据这些信息来创建某个Remote Server上的对应的远程对象,并调用其对应的方法。这整个过程中如果发生了Exception或者方法调用的返回里包含了Exception,那么我们会进行路由重试。该Handler会拦截掉Message,并中止Message在责任链上的传递。所以该Handler会被设计为末尾节点(Terminator Handler)。
Question 1:
如果Remote Server上的远程对象内部本身抛出了Exception,而非网络或其他非正常的Exception,那么我们就不该去做Retry的动作了。所以我们需要识别出哪些Exception是Remote Server上的远程对象内部本身抛出的,而哪些Exception是因为网络或服务器Down掉等非正常原因造成的。
Solution:
在Remote端,我们对远程对象也使用该Remoting Infrastructure的AOP框架,在消息处理的责任链(Chain of Responsibility)上插入一个Exception Handler,将远程对象方法执行后所抛出的异常全部转化为一个我们自定义的RemoteInnerException类型。
这样在客户端的Retry Route的Handler里,我们创建Remote端的远程对象并调用其方法的过程中如果出现了Exception,那么我们会判断Exception的具体Type,如果是RemoteInnerException,那么说明是Remote端远程对象内部本身抛出了异常,那么就不作Retry的动作,否则便说明是因为网络或服务器Down掉等非正常原因造成了调用异常,那么我们就会进行路由重试。
Question 2:
在每次方法调用的时候我们都会重新去创建一个远程对象,这样在User看来,整个调用就是一个SingleCall模式,而无论你的服务器端是按照什么模式来发布的远程对象。这样远程对象的状态就无法保存,所以我们就只能支持无状态,必须含有无参数构造方法的远程对象。
见下次........[Remoting Discussion(三)].