Re: Possible Bugs - extended & one more bug
Erez Hadad <[email protected]> Mon, 26 Sep 2005 23:02:46 +0300
| Newsgroups | gmane.comp.corba.orbacus |
|---|---|
| Message-ID | <[email protected]> |
Hi Dion, Currently I'm not using any IDL since I'm using my own custom marshalling. As for usage, consider the following example: 1. A client sends a request to the sender. The sender uses a default (DSI) servant. 2. The DSI servant at the sender receives the request and instatiates a new RC into which it stores the DSI request data (operation, target object, parameters, etc) 3. The DSI servant marshals the RC into a byte buffer and puts it into a custom transport (this is where the fast custom marshalling is applied). 4. The receiver receives the byte buffer and unmarshals the RC (again, using the fast custom unmarshalling). 5. The receiver constructs a DII request from the RC and executes it locally (collocated). As far as I can tell, the fastest portable method of marshalling is: 1. Create a CORBA.portable.OutputStream from the ORB 2. Write the RC contents to the OutputStream 3. Create a CORBA.portable.InputStream from the OutputStream 4. Read the InputStream as a byte sequence (using read_octet until getting a CORBA::MARSHAL exception) into a buffer. To unmarshal, do the same except you write the byte buffer to the OutputStream and read the RC contents from the InputStream. Note that this method does not require an Any nor a Codec. The only drawback this method has is that it allows interoperability only between ORBs using the same CDRs (big- or little-endians). This is because using a Codec would force using an Any with all the added cost I told you before. Complete portability cab be gained by placing a custom CDR tag at the sender's OutputStream and tweaking the InputStream at the receiver (_OB_readEndian). This may be still considered somewhat portable since it does not modify the ORB. Defining the RC as a value type would still not be completely portable since the Codec is still required for adding the CDR tag. To use a Codec you need an Any, going back to square 1. Generally, I see no advantage in this. Please let me know of any further suggestions. Regards, Erez Hadad On Monday 26 September 2005 21:43, Dion Picco wrote: > Hi Erez, > > (comments inlined...) > > On Mon, Sep 26, 2005 at 08:51:28PM +0300, Erez Hadad wrote: > > Hi Dion, > > > > You were right in your analysis of my specific usage, only I didn't use a > > value type :) > > > > I should start with an apology: after further enquiry into the standard, > > it seems that vendors are not required, but are rather permitted, to > > enforce java.io conformance to the CORBA.portable streams. Thus, some of > > my corrections (e.g. available()) are not entirely required. Furthermore, > > the implementation of write(int) in Sun's own J2SE ORB (1.4.2) is > > semantically different from java.io.OutputStream.write(int) - it is meant > > to write array length fields and thus write the entire integer - not just > > the > > least-significant byte. In that sense, it justifies your original > > implementation and makes my "correction" of write(int) a mistake. I'm > > sorry for misleading you, even though my intentions are honest. > > That is okay. It is unfortunate that Sun decided to use this write() > method in this fashion. It really breaks the intended usage of the > method and they certainly could have easily used another method (like > write_long) to write the array length header. I am going to leave the > write method the way it was to begin with to remain in sync with the Sun > ORB. > I am going to add the available() method anyway since its such an easy > modification. > > > As for my specific problem: > > I'm working on a mechanism that relays CORBA requests, and I need it to > > be as fast as possible, without breaking CORBA compliance. Thus, I > > decided to experiment with custom marshalling. What I did is define a > > "request container" class that contains all the dynamic request data > > elements (they are all CORBA-marshallable). At the sender, I take DSI > > information and store it into the request container. Then I marshal the > > RC and convert it to a byte buffer to be sent as payload inside a > > proprietary protocol I'm using. On the receiver side, I un-marshal the RC > > again and use its data through DII to actually invoke the request. > > At first, I used an IDL struct to store the RC class's data, then write > > it into an Any using the helper class and then marshal the Any into a > > byte-buffer using a Codec. The reverse process was used at the receiver. > > However, this seems quite inefficient, especially in a multi-threaded > > environment (as is my case): each RC requires instantiating a new struct, > > a new Any (for containing the marshalled struct) and a new Codec (since > > the standard does not define whether a Codec can be used safely by > > multiple threads simultaneously and if it imposes thread-contention > > costs). Furthermore, the process itself seems unnecessarily costly: > > writing into an Any is actually marshalling the data and processing it > > for TypeCode (which I don't need since I'm working with a fixed type) > > then scanning it again to convert with a Codec to get the buffer which I > > put into my transport. A total of at least 3 passes over the data beyond > > the actual marshalling. Out of these 3 passes, at least 2 are redundant > > in my case: I assume all endpoints use the same CDR so the Codec is not > > required, and I don't need the TypeCode since I'm using a fixed type. So, > > I decided to use the > > portable.OutputStream/InputStream directly, only I needed a portable way > > of converting the contents of the portable stream into a byte sequence. > > Thus, I came to our current issue: I write the contents of an RC directly > > to a portable.OutputStream, convert it to a portable.InputStream and read > > it as a byte stream. The reverse process is used to retrieve an RC out of > > a byte stream. Too bad CORBA/Java does not allow to constuct a portable > > stream over a standard Java Input/Output stream - I could have saved > > another pass. Last, to avoid portability problems arising from the > > mistakes I started with, I'm using read_octet and write_octet to process > > the portable streams as byte streams. > > As for value types, I see no speed or portability advantage in using > > their specific marshalling. > > > > Please enlighten me with any further thoughts or insights you might have > > of my problem. > > > > Sincerely, > > Erez Hadad > > Can you show me your RC idl definition as well as some client-side > invocation examples? I might be able to shed more > light on the problem with a little more specific knowledge of how you > are trying to perform your task. For example, using a valuetype might > allow you to forego the need to utilize an Any (as well as the typecode) > and would act in place of your struct. Or if there are a limited number > of functions to be invoked on the server-side, you might be able to > utilize an AdapterActivator. Or, you might have to do what you are > doing already ;) > > Cheers. _______________________________________________ OB-Users Mailing List - [email protected] http://mail.ooc.nf.ca/mailman/listinfo/ob-users Visit our support FAQ before you send a message. http://www.orbacus.com/faq/support.html