Native Extensions

I noticed on the road-map this item under .NET Interop:

[P3] COM: for Win32OLE compatibility

Is that the same thing as supporting native extensions? If not, is it on
the roadmap to support such a thing? Also, is there a workaround, like
replacing files in the gem installation with a .NET wrapper? I’d love to
use IronRuby to embed Thin or Mongrel in my .NET services, but from from
my few experiments it looks like most of the networking libraries these
servers use tend to rely on native dll’s.

Native extension support is not on the roadmap for 1.0. Win32OLE support
is actually in there now, because of the Dynamic Language Runtime’s
support for dispatching to COM objects. So IronRuby’s version of
win32ole.rb uses IronRuby’s OLE support, rather than depending on native
code.

The current work-around for libraries which use native code to
communicate with the OS or Ruby is to rewrite those using .NET so
IronRuby can use them. Mongrel is actually \mostly Ruby code, as most
Ruby libraries which use native code; there is usually a very small part
of the library which depends on native code. For Mongrel, the HTTP 1.1
parser is the only native piece; rewriting that in C# would allow you to
run Mongrel on .NET.

IMO, after 1.0 would be the time to consider supporting the native Ruby
API.

~Jimmy


From: [email protected]
[[email protected]] on behalf of Nathan Stults
[[email protected]]
Sent: Tuesday, October 06, 2009 4:18 PM
To: [email protected]
Subject: [Ironruby-core] Native Extensions

I noticed on the road-map this item under .NET Interop:

[P3] COM: for Win32OLE compatibility

Is that the same thing as supporting native extensions? If not, is it on
the roadmap to support such a thing? Also, is there a workaround, like
replacing files in the gem installation with a .NET wrapper? I’d love to
use IronRuby to embed Thin or Mongrel in my .NET services, but from from
my few experiments it looks like most of the networking libraries these
servers use tend to rely on native dll’s.

Posted via http://www.ruby-forum.com/.


Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Thanks for the tip. It looks like the Http Parser is generated via
Ragel, and it appears there is a Java version of the language file, so
theoretically all I should have to do is learn Ragel and port that file
to C#, piece of cake :slight_smile: Then I suppose I’d need a patched version of
mongrel that required the new .NET HTTP parser dll instead of the C
version? Is that how that would work?

Hi Nathan,
yes, that’s basically what you need to do:

1- rewrite the C (or Java) bits of the http parser in C# and let Ragel
generate the rest
2- wrap everything up in a layer to expose the needed methods to
IronRuby
3- make sure to require your newly built http11.dll in the ruby part
of the mongrel library
4- have fun.

I did the same for hpricot and json (whose parsers are generated using
Ragel), so I guess that should work for Mongrel too :slight_smile:

On Wed, Oct 7, 2009 at 03:09, Nathan Stults
[email protected] wrote:

Schementi
The current work-around for libraries which use native code to
~Jimmy
[P3] COM: for Win32OLE compatibility
Ironruby-core mailing list
http://rubyforge.org/mailman/listinfo/ironruby-core


Daniele A.
http://www.clorophilla.net/blog/
http://twitter.com/JoL1hAHN

Presumably that workflow would work.

An alternative is to write a thin Ruby or C# wrapper that wraps the
native HTTP parser using either FFI
(Bridging MRI, JRuby & Rubinius with FFI - igvita.com
or http://www.javaworld.com/community/?q=node/1722), or pinvokes.
IronRuby supports neither FFI nor Ruby/dl. So you would have to use
pinvokes from C# for now.

FWIW, another alternative is implementing something like IronClad
(Google Code Archive - Long-term storage for Google Code Project Hosting.) which would allow native extensions
to work as is, but this is a large feature.

Great, I’ll study your code to give me a head start. If I run into
trouble I’ll be sure to bug you :slight_smile: I had never heard of Ragel until I
started looking into Ruby the last couple of weeks - is it just a parser
generator like any other?

IronRuby supports neither FFI nor Ruby/dl. So you would have to use pinvokes from C# for now.

just wondering: is there a remotely vague intention of having FFI
support at some point for IronRuby ?

just curious if someone actually thought about implementing this,

– Thibaut

It’s is a large workitem, so it would be post 1.0. Tomas thinks some of
the code can be reused from the IronPython equivalent (the ctypes
library), but it would still be a fair amount of work.

I think Win32API is a weak equivalent, and someone could start playing
with it for accessing native extension. There would be work on the
native extensions to expose the functionality as dllexports, and this
can be pushed on right now without waiting for IronRuby to support
FFI…

+1 for CLR/C# extensions

Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

On Wed, Oct 7, 2009 at 8:36 PM, Tomas M.
<[email protected]

On the other hand, using a native extension is worse than using a pure
C#/Ruby equivalent. Native interop doesn’t work in partial trust
(Silverlight, web servers, etc) and supporting more platforms (Windows,
Linux, MacOS, etc) would need more work. So if there is some useful Ruby
native extension with stable API it makes sense to implement it in Ruby
with .NET interop or directly in C#.

Tomas

Yup, we will need a mix of both approaches. Reimplementing in C# gives
more flexibility in being able to run on any CLR, but is also expensive.
Being able to use FFI can give access to more extensions quickly and
cheaply, but will not have the same reach as a managed reimplementation.

The HttpHandler is the only piece you’ll have to replace, since it’s
specifically for IIS, and provide your own hookup to the server you
choose. You’ll have to construct the HttpRequest/Response objects also,
but all-in-all it should be pretty straight-forward. Those two look like
great .NET web-server projects; “webserver” is like a web-framework too,
which is cool. Whatever you do, DON’T use Chiron, as it’s not intended
to be a real web-server (it doesn’t support POST requests, and only
listens on localhost).

~js

Ahh nice clean, brief code. Now this I can handle. I do have a question
though about threading - it looks like in your implementation the whole
apparatus is essentially single threaded, i.e. there is a single handler
maintained by the factory, and the single handler locks itself for the
duration of the request - this suggests to me that ScriptEngine (or at
least RubyEngine) is not thread-safe? Is that the case, or was the
threading designed for simplicity? For instance, if in my implementation
I took a lock on the RubyEngine just long enough to obtain a new scope
to handle the request, would that do? Or does it pretty much need to be
1 thread = 1 script engine? If the latter is the case, would there be
any caveats to maintaining a small pool of engines that could handle a
few simultaneous requests? To be honest, this almost certainly won’t
make a bit of difference to my use case of embedding a web server in an
application server, traffic just won’t be that high, but mostly I’m just
curious about the platform.

Thanks,

Nathan

That lock is there because Rails wasn’t thread-safe at the time of
writing; it has no reflection on whether ScriptEngine is thread-safe. I
believe ScriptEngine is thread-safe, as only one ScriptEngine per
language can EVER exist when you have only one ScriptRuntime.

Rails is much more thread-safe than it used to be, so that lock should
be removed; IMO it should have never been there as the Rack adapter
shouldn’t care about Rails; it should lock if the rack.multithreaded
flag is true.

~js


From: [email protected]
[[email protected]] on behalf of Nathan Stults
[[email protected]]
Sent: Thursday, October 08, 2009 12:26 AM
To: [email protected]
Subject: Re: [Ironruby-core] Native Extensions

Ahh nice clean, brief code. Now this I can handle. I do have a question
though about threading - it looks like in your implementation the whole
apparatus is essentially single threaded, i.e. there is a single handler
maintained by the factory, and the single handler locks itself for the
duration of the request - this suggests to me that ScriptEngine (or at
least RubyEngine) is not thread-safe? Is that the case, or was the
threading designed for simplicity? For instance, if in my implementation
I took a lock on the RubyEngine just long enough to obtain a new scope
to handle the request, would that do? Or does it pretty much need to be
1 thread = 1 script engine? If the latter is the case, would there be
any caveats to maintaining a small pool of engines that could handle a
few simultaneous requests? To be honest, this almost certainly won’t
make a bit of difference to my use case of embedding a web server in an
application server, traffic just won’t be that high, but mostly I’m just
curious about the platform.

Thanks,

Nathan

Good news, thanks. In the Handle method of the IIS.cs, you are setting
two scope variables, __request and __response - are these variables
known to Rack, or are those set for the convenience of a IronRuby
adapter aware programmer to use from ruby if desired?

Thanks,

Nathan

I spent a day chasing my tail and, upon catching it, realized my
DLR/IronRuby knowledge just isn’t up to the challenge. Maybe someday. As
an alternative, I’m going to see if the IronRuby.Rack stuff on Git can
teach me what I need to wire Rack up to one of these embeddable .NET
HTTP servers: http://www.codeplex.com/webserver,
http://runkayak.com/getstarted, which ought to provide the same benefit,
and possibly perform a little better as well. Is anyone aware of other
embeddable .NET HTTP server projects?

(http://github.com/jschementi/ironruby/tree/92932a672921a03210c8aefe23ac
0a7d6996ed2d/Merlin/Main/Hosts/IronRuby.Rack)

They are an implementation detail; used to manipulate the request and
response from ruby (see later on down in the massive handle method).
In my forks “rackupdate” branch I don’t think they exist anymore, as
I’m refactoring that code a bit.

~Jimmy
Sent from my phone

On Oct 8, 2009, at 11:12 AM, “Nathan Stults”
<[email protected]

Thank you - I’m new to GitHub, so I didn’t notice that branch - I’ll get
that one as a guide instead. On a related note, is there an accepted /
preferred / traditional path I should follow in regards to re-mixing
your code? I presume your rack integration stuff is licensed the same as
IronRuby? In any case, is there any problem with me blending your work
into a separate library intended to act as a generic adapter between
Rack and an embedded .NET server and publishing as a separate library
(following attribution, licensing rules, etc)? That is what I would
normally do, but all this forking madness has made me second guess. BTW,
thanks for your time in answering my endless questions. You guys have
done an amazing job on all this stuff, very exciting possibilities.

There is no problem with you taking any part of anything in the IronRuby
repo and including it in another library; here are all the licenses
IronRuby’s releases contain:
http://github.com/ironruby/ironruby/tree/master/Merlin/Main/Languages/Ruby/Licenses.
CJ recently did a good job of mapping each directory in the entire
IronRuby tree to a license, so I’ll let him chime in about where that
data is.

So, feel free to do you work separately for now. I’d be interested in
taking back any fixes you have for the rack-specific pieces, so I’ll
figure out how to make that happen on my side when the time comes.

Let me know how things go, and don’t hesitate to ask any more questions,
~Jimmy


From: [email protected]
[[email protected]] on behalf of Nathan Stults
[[email protected]]
Sent: Thursday, October 08, 2009 12:10 PM
To: [email protected]
Subject: Re: [Ironruby-core] Native Extensions

Thank you - I’m new to GitHub, so I didn’t notice that branch - I’ll get
that one as a guide instead. On a related note, is there an accepted /
preferred / traditional path I should follow in regards to re-mixing
your code? I presume your rack integration stuff is licensed the same as
IronRuby? In any case, is there any problem with me blending your work
into a separate library intended to act as a generic adapter between
Rack and an embedded .NET server and publishing as a separate library
(following attribution, licensing rules, etc)? That is what I would
normally do, but all this forking madness has made me second guess. BTW,
thanks for your time in answering my endless questions. You guys have
done an amazing job on all this stuff, very exciting possibilities.

Maybe Microsoft could host the IronRuby standard library on its new CDN
(ScottGu's Blog
oft-ajax-cdn.aspx) for all to enjoy :slight_smile: Most of the individual library
files seem small enough, and if it works for .JS files, it should work
for Ruby, no? Especially if some local caching were baked in.