Re: [Rubydotnet-developer] rubydotnet - first announcement
Status: Alpha
Brought to you by:
thomas
From: John R. P. <jo...@pi...> - 2003-09-04 12:32:03
|
> Hi, > > I've made some progress with my own rubydotnet project. Instead of using > sockets for communication or hosting the CLR, my module is written as a > managed C++ extension. With this approach I have managed to get the basic > functionality running with 245 lines of C++ code and 50 lines of ruby. Does this mean a joint effort is slipping away from all of us? R2 of our bridge includes a C++ extension module as well in approx 300 lines of code (if that is a measure of something). Additionally, we also have approx. 250 automated unit tests using TestUnit for both the socket and direct C++ versions of the bridge. > One of the things that I have done differently is the class discovery. > Instead of using a DotNet object as root for the hierarchy I'm using the new > Module#const_missing feature in ruby-1.8.0, which means that I can do > something like this: > > require 'dotnet' > include System.Collections > > a = ArrayList.new > > a.count # => 0 > a.add(1) > a.count # => 1 I like this -- didn't know it was a new feature of module in 1.8. Can you do it without the "include <namespace>" line? We really like that our bridge flattens the .NET namespaces (but we can still use the FQN if necessary). > I've also got a Kernel::reference() method you can call to reference > whatever assemblies you may want to use. Again, nice trick. I like it. > I'm worried about .net class inheritance from ruby, though, from a garbage > collection stand point. When I pass a ruby object to .net I wrap it in a > RubyDotNet::Object .net wrapper and vice versa with .net objects that are > passed to ruby. These wrappers lock the wrapped objects from being garbage > collected using rb_gc_register_address on the ruby side an > System::Runtime::InteropServices::GCHandle on the .net side. If you inherit > a .net class from ruby you will need the ruby object and the .net object to > reference each-other, but then they will be locked in memory and will never > be garbage collected. I'm aware that this is just a special case of a cyclic > reference problem that exists with my approach, but it is not too likely to > bite you in most other cases. We took the approach in the first two releases of our bridge that GC is not high on our list. If we are a leaky until process exit occurs, well, we can still get a lot of work done. We will address GC issues in upcoming releases of our bridge. > How have you guys addressed this problem? Do you have any idea about how to > handle this problem? Technically, I'd look to break the cycle you mention by using a WeakReference on one side or the other of the interop. I don't know if that is possible, but that is what I'd search for. I believe both Ruby and .NET have WeakReference concepts, but I could be wrong. > Have you made any progress on the thread safety issue with callbacks from > .net to ruby? I'm wondering if it is necessary to make some kind of > synchronized queue, where you post you callbacks and then have a pool of > ruby threads reading the jobs from that queue as they are posted. Or maybe > we could lobby match to add some locking to ruby to make it thread-safe? I > know too little about this :-) Yep! You are right! Our socket edition of the bridge handles this correctly and utilizes a message queue concept. We call the concept the Post Office in our classes in the code. Callbacks are handled and posted on the correct thread in Ruby and/or .NET. As an aside, we have yet to make our C++ extension follow this same behavior. Regards, John |