You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by "Alan D. Cabrera" <li...@toolazydogs.com> on 2005/09/15 22:46:15 UTC

TriFork CORBA donation

How are things going on this? 

I hope that what will be donated will not be "gold plated" so that the 
community can participate in its integration into Geronimo.  I know that 
a few people, including people from OpenORB, are interested in helping out.


Regards,
Alan




Re: TriFork CORBA donation

Posted by Jacek Laskowski <jl...@apache.org>.
Kresten Krab Thorup wrote:
> Hi there, ...

Hi Kresten,

I'm not prepared to comment on the details, but have a general question.

> - nio/select is used to avoid having an active thread listening for  
> incoming messages

It sounds like Java 5. Will it require this Java version? Geronimo is 
1.4-based.

> Kresten Krab Thorup

Jacek

Re: TriFork CORBA donation

Posted by "Alan D. Cabrera" <li...@toolazydogs.com>.
How are things going?  Do you think that it's possible to get the code 
in our repo and you work from there?


Regards,
Alan

Kresten Krab Thorup wrote, On 9/16/2005 9:04 AM:

> Hi there, ...
>
> It has been up to a slow start, but I have finally gotten something  
> rolling now.
>
> As I have mentioned earlier, I wanted to redo the I/O subsystem, and  
> this is going quite well.  The first milestone I am targeting is to  
> be able to do client side stream-based invocations; i.e. be able to  
> do invocations using a generated stub.  This is a sufficiently small  
> thing that it is doable relatively quick (sigh), and also gets around  
> to do most of the hairy parts of I/O.
>
> This part I am writing from scratch, since the new I/O transcends  
> most of this code.  This part is quite close to completion, and if  
> someone wants to see the code I'd be happy to share it.  Here, I have  
> some notes on the I/O system; ...
>
> The I/O system is designed with the following properties:
>
> - it eliminates copying (double buffering)
> - i/o can be off-loaded to a separate selector thread
> - nio/select is used to avoid having an active thread listening for  
> incoming messages
> - transport buffers are allocated only once, and have fixed size.
> - facilitate multiplexing requests and bidirectional invocations.
>
> In this terminology, a transport (which may be a socket or an in- 
> memory pipe, for instance) has the following API:
>
> interface Transport {
>
>    InputChannel getInputChannel();
>    OutputChannel getOutputChannel();
>    void setInputHandler(InputHandler handler);
>    void close();
>    void start();
>
>    void signalCondition(Object conditionKey, Object user_data);
>    Object waitForCondition(Object conditionKey);
> }
>
> Only one thread can have the input channel at one time, and only one  
> thread can have the output channel.  Calls to getInputChannel(), and  
> getOutputChannel() will block until the channel is available.  If  
> someone else has "taken" the channel, then the requestor will block  
> until the other party relinquishes it.  This semantics is used to  
> handle multiplexing multiple client threads using the same transport  
> to do invocation, and similarily on the server side to  handle  
> multiple threads sending responses.
>
> interface Channel {
>    void close();
>    void relinquish();
> }
>
> Closing a channel semantically puts an end-of-stream marker into the  
> channel's data.  For an OutputChannel, once the EOS reaches the  
> underlying transport layer (i.e. the data ahead of it has been  
> written), it is effectuated as a half-close.  For an InputChannel,  
> the half-close is effectuated right away, and the client of the input  
> stream will read and end-of-file when there is no more buffered data  
> available.
>
> When input becomes available in the underlying transport, and there  
> is no current thread that owns the input channel, then control is  
> passed to the input handler in a new thread taken from some worker pool.
>
> The transport also has a built-in signaling mechanism, that allows  
> the InputHandler to parse a message header (including e.g. a  
> request_id) and then pass control to someone waiting for a given  
> reply.  Such waiters can also participate in the processing of  
> available input.
>
> An output channel allows you to put data into the transport, and  
> provides a mechanism to set markers.  Markers are used to handle  
> fragmentation and other things where a size needs to be written into  
> some place in the stream.
>
> interface OutputChannel extends Channel {
>     putByte(byte value);
>     put(byte[] data, int off, int len);
>     // ... other put methods ...
>
>    void flush();
>
>    OutputChannelMark setMark(OutputChannelMarkHandler handler);
> }
>
> Now, if the output channel's buffer runs full, then the mark handler  
> is called, so that the
>
> interface OutputChannelMarkHandler {
>    void willFlush(OutputChannelMark mark);
> }
>
> OutputChannelMark provides a ByteBuffer-like view of the stream,  
> where index 0 is the position of the marker.  You cannot put data  
> beyond the mark's limit, which is equal to the amount of bytes  
> written to the channel since the mark.
>
> interface OutputChannelMark {
>     void putByte(int idx, byte value);
>     void putInt(int idx, int value);
>     int limit();
>     void release();
>     OutputChannel getOutputChannel();
> }
>
> Calling release() on an OutputChannelMark will release underlying  
> buffer space up to this mark (unless of cause there is a non-released  
> marker that was set earlier in the stream).
>
> The OutputChannelMark can also give you the channel that i came from,  
> and so inside the handler you can do stuff like this to handle GIOP  
> fragmentation dynamically based on when the underlying buffer runs full.
>
>    class FragmentHandler implements OutputChannelMarkHandler {
>
>        void willFlush( OutputChannelMark mark) {
>             int message_size = mark.limit();
>             if (!logical_stream_has_ended) {
>                 mark.putByte(7, 2); // write "hasMoreFragments" bit
>             }
>             mark.putInt (8, message_size);  // write message size  
> into GIOP header
>
>             mark.release();
>
>            if (!logical_stream_has_ended) {
>                 mark.getOutputChannel().setMark(this);
>                 write_fragment_header();
>             }
>        }
>
>    }
>
> I use the markers to implement GIOP fragments, and also to do  
> chunking for values.  The mechanism cannot really be used for  
> encapsulations because they can span GIOP messages.
>
> So, ... on top of this abstraction layer I have implemented a fair  
> chunk of the GIOP/CDR encoding stuff up to the point where a client  
> can perform a request, but it doesn't work yet...
>
> My thinking is that once this has reached a point where I can  
> actually do a hello world invocation on a foreign ORB, then it would  
> be a good point to bring in some more people.
>
> Once we're past this, I have some larger chunks of the original  
> Trifork ORB that we can bring to play.  You're welcome to have a look  
> at the code though, and chip in with your comments.
>
>
> Kresten Krab Thorup
> krab@trifork.com
>
> "We do not inherit the Earth from our parents, we borrow it from our  
> children." Saint Exupery
>
>
>
> On Sep 15, 2005, at 10:46 PM, Alan D. Cabrera wrote:
>
>> How are things going on this?
>> I hope that what will be donated will not be "gold plated" so that  
>> the community can participate in its integration into Geronimo.  I  
>> know that a few people, including people from OpenORB, are  
>> interested in helping out.
>>
>>
>> Regards,
>> Alan
>>
>>
>>
>>



Re: TriFork CORBA donation

Posted by Kresten Krab Thorup <kr...@trifork.com>.
Hi there, ...

It has been up to a slow start, but I have finally gotten something  
rolling now.

As I have mentioned earlier, I wanted to redo the I/O subsystem, and  
this is going quite well.  The first milestone I am targeting is to  
be able to do client side stream-based invocations; i.e. be able to  
do invocations using a generated stub.  This is a sufficiently small  
thing that it is doable relatively quick (sigh), and also gets around  
to do most of the hairy parts of I/O.

This part I am writing from scratch, since the new I/O transcends  
most of this code.  This part is quite close to completion, and if  
someone wants to see the code I'd be happy to share it.  Here, I have  
some notes on the I/O system; ...

The I/O system is designed with the following properties:

- it eliminates copying (double buffering)
- i/o can be off-loaded to a separate selector thread
- nio/select is used to avoid having an active thread listening for  
incoming messages
- transport buffers are allocated only once, and have fixed size.
- facilitate multiplexing requests and bidirectional invocations.

In this terminology, a transport (which may be a socket or an in- 
memory pipe, for instance) has the following API:

interface Transport {

    InputChannel getInputChannel();
    OutputChannel getOutputChannel();
    void setInputHandler(InputHandler handler);
    void close();
    void start();

    void signalCondition(Object conditionKey, Object user_data);
    Object waitForCondition(Object conditionKey);
}

Only one thread can have the input channel at one time, and only one  
thread can have the output channel.  Calls to getInputChannel(), and  
getOutputChannel() will block until the channel is available.  If  
someone else has "taken" the channel, then the requestor will block  
until the other party relinquishes it.  This semantics is used to  
handle multiplexing multiple client threads using the same transport  
to do invocation, and similarily on the server side to  handle  
multiple threads sending responses.

interface Channel {
    void close();
    void relinquish();
}

Closing a channel semantically puts an end-of-stream marker into the  
channel's data.  For an OutputChannel, once the EOS reaches the  
underlying transport layer (i.e. the data ahead of it has been  
written), it is effectuated as a half-close.  For an InputChannel,  
the half-close is effectuated right away, and the client of the input  
stream will read and end-of-file when there is no more buffered data  
available.

When input becomes available in the underlying transport, and there  
is no current thread that owns the input channel, then control is  
passed to the input handler in a new thread taken from some worker pool.

The transport also has a built-in signaling mechanism, that allows  
the InputHandler to parse a message header (including e.g. a  
request_id) and then pass control to someone waiting for a given  
reply.  Such waiters can also participate in the processing of  
available input.

An output channel allows you to put data into the transport, and  
provides a mechanism to set markers.  Markers are used to handle  
fragmentation and other things where a size needs to be written into  
some place in the stream.

interface OutputChannel extends Channel {
     putByte(byte value);
     put(byte[] data, int off, int len);
     // ... other put methods ...

    void flush();

    OutputChannelMark setMark(OutputChannelMarkHandler handler);
}

Now, if the output channel's buffer runs full, then the mark handler  
is called, so that the

interface OutputChannelMarkHandler {
    void willFlush(OutputChannelMark mark);
}

OutputChannelMark provides a ByteBuffer-like view of the stream,  
where index 0 is the position of the marker.  You cannot put data  
beyond the mark's limit, which is equal to the amount of bytes  
written to the channel since the mark.

interface OutputChannelMark {
     void putByte(int idx, byte value);
     void putInt(int idx, int value);
     int limit();
     void release();
     OutputChannel getOutputChannel();
}

Calling release() on an OutputChannelMark will release underlying  
buffer space up to this mark (unless of cause there is a non-released  
marker that was set earlier in the stream).

The OutputChannelMark can also give you the channel that i came from,  
and so inside the handler you can do stuff like this to handle GIOP  
fragmentation dynamically based on when the underlying buffer runs full.

    class FragmentHandler implements OutputChannelMarkHandler {

        void willFlush( OutputChannelMark mark) {
             int message_size = mark.limit();
             if (!logical_stream_has_ended) {
                 mark.putByte(7, 2); // write "hasMoreFragments" bit
             }
             mark.putInt (8, message_size);  // write message size  
into GIOP header

             mark.release();

            if (!logical_stream_has_ended) {
                 mark.getOutputChannel().setMark(this);
                 write_fragment_header();
             }
        }

    }

I use the markers to implement GIOP fragments, and also to do  
chunking for values.  The mechanism cannot really be used for  
encapsulations because they can span GIOP messages.

So, ... on top of this abstraction layer I have implemented a fair  
chunk of the GIOP/CDR encoding stuff up to the point where a client  
can perform a request, but it doesn't work yet...

My thinking is that once this has reached a point where I can  
actually do a hello world invocation on a foreign ORB, then it would  
be a good point to bring in some more people.

Once we're past this, I have some larger chunks of the original  
Trifork ORB that we can bring to play.  You're welcome to have a look  
at the code though, and chip in with your comments.


Kresten Krab Thorup
krab@trifork.com

"We do not inherit the Earth from our parents, we borrow it from our  
children." Saint Exupery



On Sep 15, 2005, at 10:46 PM, Alan D. Cabrera wrote:

> How are things going on this?
> I hope that what will be donated will not be "gold plated" so that  
> the community can participate in its integration into Geronimo.  I  
> know that a few people, including people from OpenORB, are  
> interested in helping out.
>
>
> Regards,
> Alan
>
>
>
>