PDA

View Full Version : disconnect from CAO



cjack
09-05-2006, 01:26 PM
Hi,
After being really impressed by the elegance of introducing remoting through the usage of Spring.NET - there popped-up one question:

By using a CAO through the CaoExporter is there any way to explicitly disconnect the CAO (on the server)?

For instance I would like having the CAO to implement some sort of a disconnect() method, that would dispose the CAO on the server - not just relying on the lease to expire...
(So far as I have seen from the code, the CaoExporter actually exports a dynamic proxy created by a RemoteObjectProxyTypeBuilder. After an instance of this dynamic proxy has been marshalled by ref., there is no reference kept and thus I can't do something like RemoteServices.Disconnect() later on to disconnect - right?)
Regards
Christian

Bruno Baia
09-05-2006, 02:18 PM
Hi Christian,

CaoExporter implements IDisposable with Dispose method disconnecting the remote object.

Have you try something like that on the server :


<object id="counter1" type="Spring.Remoting.SimpleCounter, Spring.Services.Tests" singleton="false">
<constructor-arg type="int" value="1" />
</object>

<object id="counter1CaoExporter" type="Spring.Remoting.CaoExporter, Spring.Services">
<property name="TargetName" value="counter1" />
</object>



IApplicationContext ctx = ContextRegistry.GetContext();
((IDisposable)ctx.GetObject("counter1CaoExporter")).Dispose();


Cheers,
Bruno

cjack
09-05-2006, 02:27 PM
Bruno,

I think this is a misunderstanding.
I don't want to disconnect the CaoExporter (which is a singleton SAO) BUT the exported (by CaoExporter) CAO - once the client is done with it!

Thanks in advance
Christian

Bruno Baia
09-05-2006, 03:27 PM
Ok, i see what you mean.

For CAO support, we decided to use a "SAO CAO factory" (ICaoRemoteFactory), a SAO factory that creates CAOs. It allows you to keep the CAO class on the server, like that you only need the interface on the client.

Then, the "SAO CAO factory" implementation (CaoExporter+CaoRemoteFactory), uses the RemoteObjectFactory to ensure that GetObject method return MBR objects, it never exports them (there is no RemotingServices.Marshal call in the factory).
The RemoteObjectFactory (with the associated RemoteObjectProxyTypeBuilder) takes any kind of object and make it "remotable" (inherits from MarshalByRefObject- see BaseRemoteObject class) using dynamic Proxy - No need to inherit from MarshalByRefObject. In any case it exports the object.

"SAO CAO factory" implementation :


public object GetObject()
{
RemoteObjectFactory factory = new RemoteObjectFactory();
factory.Target = objectFactory.GetObject(targetName, ObjectUtils.EmptyObjects);

return factory.GetObject();
}


Btw, we can add a test to check if the object is already a MBR, and there is maybe an error :
The object returned by the factory just need to be serializable, but i'm not able to remember why i used RemoteObjectFactory to create a MBR... this works, but it's maybe too much here.

-Bruno

cjack
09-06-2006, 07:26 AM
Bruno,
we are getting closer regarding our mutual understanding...

Still the problem that I have is, that the SAO CAO factory is always returning a MBR which is the target object (from CaoExporter) wrapped into a dynamic proxy (generated by the RemoteObjectProxyTypeBuilder).
For that reason I can not call RemoteServices.Disconnect(targetObject), because it is not the targetObject which was returned as MBR and thus registered as remote object with the .NET remoting infrastructure but the wrapping dynamic proxy.

One solution that I see to give the ability to explicitly disconnect a CAO on request of a client is, to have the dynamic proxy (generated by the RemoteObjectProxyTypeBuilder) implement IDisposable by calling RemoteServices.Disconnect(this).

One minor comment on the use of the RemoteObjectProxyTypeBuilder: As far as I can see is a new dynamic proxy type generated on each invocation of CaoExporter.getObject(). But wouldn't it be sufficient (and eaven more efficient) to generate the proxy type only once per CaoExporter?

/Christian

Bruno Baia
09-06-2006, 12:42 PM
Still the problem that I have is, that the SAO CAO factory is always returning a MBR which is the target object (from CaoExporter) wrapped into a dynamic proxy (generated by the RemoteObjectProxyTypeBuilder).
For that reason I can not call RemoteServices.Disconnect(targetObject), because it is not the targetObject which was returned as MBR and thus registered as remote object with the .NET remoting infrastructure but the wrapping dynamic proxy.

One solution that I see to give the ability to explicitly disconnect a CAO on request of a client is, to have the dynamic proxy (generated by the RemoteObjectProxyTypeBuilder) implement IDisposable by calling RemoteServices.Disconnect(this).

I need to investigate here, RemotingServices.Disconnect is a "server side" method to unregister objects published, you cannot call Disconnect on a Proxy. So, Disconnect can only be called on the "SAO CAO factory" on the server.
Make the CAO implement IDisposable is a solution to investigate, but it seems more complicated than RemoteServices.Disconnect(this).



One minor comment on the use of the RemoteObjectProxyTypeBuilder: As far as I can see is a new dynamic proxy type generated on each invocation of CaoExporter.getObject(). But wouldn't it be sufficient (and eaven more efficient) to generate the proxy type only once per CaoExporter?

You right, this needs some modications to improve performances.


Cheers,
Bruno

cjack
09-06-2006, 01:39 PM
Well as initially stated in the thread I am really infected by the way remoting is supported by spring...

Since this has been passed my first proof of concept testing I am willing to apply this style of remoting in a running project of mine - provided that the mentioned issues are handled...

What are your current development plans regarding the spring remoting area? Are there any major advancements to be expected in the very next time?

If there are no plans at the spring team and I would proceed to develop my own 'enhancements', would you be interested into that and what are your proceedings regarding contributions?

Thanks anyway
Christian

Mark Pollack
09-07-2006, 04:44 AM
Hi Christian,

We don't have any items on the development roadmap regarding remoting functionality but that obviously isn't written in stone given feedback from users. Aside from the points you mention (disposing CAOs and proxy optimization) what enhancements to you have in mind? I had thought of some integration with remoting events with the IEventRegistry but at the end felt that .net remoting events were too brittle to bother with and one would best be served by promoting the use of "true" messaging middleware. Generally speaking, it seems there are many features one would best be advised to say away from in the .NET remoting stack.

Regarding contributions, we are certainly open to code contributions, those that come with unit tests are even more welcome. :p An appropriate Spring.NET team member would review the contribution and determine if it should be introduced into the code base, write docs, etc. Continued contribution is the path to becoming a Spring.NET team member.

Cheers,
Mark

Mark Pollack
09-07-2006, 05:01 AM
Hi again,

I just remembered that there was a suggestion to control which objects can be retrieved by calling IRemoteFactory.GetObject. Currently any object in the IoC container can be requested. Providing the RemoteFactory implementation a list of object names to restrict this would offer more manageability.

Cheers,
Mark

cjack
09-07-2006, 03:51 PM
Hello Mark,

I was just digging into the remoting code and made some changes to better fit my personal demands:

RemoteObjectProxyTypeBuilder

Refactored into a namespace String.Remoting.Support, same for SaoRemoteObjectProxyTypeBuilder which now extends RemoteObjectProxyTypeBuilder. This reduces some copy&paste code and also aids for better reuse of the ~ProxyTypeBuilder internaly in place of RemoteObjectFactory...CaoExporter

The lifecycle properties now configure the lease time of the CAO returned by the internal CaoRemoteFactory!!! (w/o this change the lease time of the internal CaoRemoteFactory was configured which doesn't make sense, since it should have always infinite lifetime. The lease time of the CAOs was always the .NET default...)CaoExporter.CaoRemoteFactory

Now builds only one proxy-type (not a new one for each getObject() call via a new RemoteObjectFactory) that is reused to create remotable proxy instances of the target objects.
The base type of proxy-types generated for CAO objects now is BaseCao which in turn extends BaseRemoteObject.
BaseCao explicitly implements IDisposable.Dispose(). This allows for clients to explicitly disconnect their CAOs through:
((IDisposable)clientCaoObj).Dispose().


ILeaseTime

Interface introduced for the lifecycle properties (implemented by the exporters, BaseRemoteObject, ProxyTypeBuilder(s) and RemoteObjectFactory).If one "appropriate Spring.NET team member" is interested in looking into my changes. How would you like to receive my patches?

/Christian

Bruno Baia
09-08-2006, 09:16 AM
Hi Christian,

You can attach a zip file to your post or send it to me. (i sent you a private message with my email).

I'll take a look this week-end, there is some points i disagree.


Cheers,
Bruno

Bruno Baia
09-12-2006, 09:47 AM
Hi Christian,

Thanks for the patch, I'm looking forward to your changes to integrate them to Spring.Remoting.
I've got some questions :



CaoExporter.CaoRemoteFactory

The base type of proxy-types generated for CAO objects now is BaseCao which in turn extends BaseRemoteObject.
BaseCao explicitly implements IDisposable.Dispose(). This allows for clients to explicitly disconnect their CAOs through:
((IDisposable)clientCaoObj).Dispose().

Why not make BaseRemoteObject directly implement IDisposable ?



ILeaseTime

Interface introduced for the lifecycle properties (implemented by the exporters, BaseRemoteObject, ProxyTypeBuilder(s) and RemoteObjectFactory).

I'll change the name of the interface to ILifetime because of the IsInfinite property.
I'll maybe move it to Support namespace with the ICaoRemoteFactory interface and the BaseRemoteObject abstract class.


What do you think ?

Cheers,
Bruno

cjack
09-12-2006, 12:15 PM
Hi Bruno,

to answer your questions:


Why not make BaseRemoteObject directly implement IDisposable ? If BaseRemoteObject would implement the Dispose(), every (possibly singleton) SAO exported by the SaoExporter could get disconnected from a client as well - so I though this might not be desired.


I'll change the name of the interface to ILifetime because of the IsInfinite property.
I'll maybe move it to Support namespace with the ICaoRemoteFactory interface and the BaseRemoteObject abstract class.I fully agree with you!
... and feelling happy that I could support you with a very little contribution, hoping the Spring team goes on with their impessive and extremley valuable work!

/Christian

Bruno Baia
09-15-2006, 08:34 AM
Hi Christian,

I refactored a little bit the remoting framework based on your contribution.
Get the latest nightly build (http://www.springframework.net/downloads/nightly/) and give it a try.

Thanks again,
Bruno