Archived

This forum has been archived. Please start a new discussion on GitHub.

How to get one byte array of a parameter in dynamic Ice?

I'm using dynamic Ice to create a request forwarder. Considering this definition:
struct PricingRequest { .... };

struct PricingInfo
{
    string mRequestId;
    string mTag;
};

struct ForwardingInfo
{
    int mPriority;
};

interface Pricer
{
    double Price(PricingInfo info, PricingRequest request);
};

["amd"] interface Forwarder
{
    double Price(ForwardingInfo forwardingInfo, PricingInfo info, PricingRequest request);
};

The idea is, I create a forwarder, which monitors on multiple pricers, and forward request to one pricer.

I use dynamic Ice to avoid unmarshalling the PricingInfo and PricingRequest. What I need on forwarder is only the ForwardingInfo which contains information such as priority.

Also, I would like to create a cache over the request. So I want to have the byte array of the request (not demarshalled), so that I can create hash table inside forwarder, and avoid send same request to pricer.

So if I try to implement it with dynamic Ice:
override this.ice_invoke_async(cb, inParams, cur) =
        if (cur.operation.Equals("Price")) then
            let communicator = cur.adapter.getCommunicator()
            let inStream = Ice.Util.createInputStream(communicator, inParams)

the inParams is an array of byte, but it includes all three parameters, the forwarding info, pricing info, and request. What I want to do is:
  1. demarshal the fowarding info, so that I know the priority.
  2. get the byte array of request without demarshalling, and check it in cache.
  3. if not hit the cache, I want to get the 2nd and 3rd parameters' byte array to invoke the pricer.

I checked the dynamic Ice, seems have no idea on how to do this. Anyone can help me? Thanks.

Comments

  • benoit
    benoit Rennes, France
    Hi,

    Did you consider passing the priority with the Ice::Context parameter instead?

    The Ice::Context is a dictionary of strings so you will need to encode/decode the priority but it will allow you to access it from the blobject ice_invoke_async implementation using the ctx member of the Ice::Current parameter.

    See Requests Contexts for more information.

    Cheers,
    Benoit.
  • Thanks, yes, context might be a solution for priority, but I have 2 parameters for pricing, the PricingInfo and PricingRequest. So PricingInfo contains some extra information, which will not be needed for create cache (I need do a hash on the byte array of PricingRequest only).

    Well, I find to skip correct size is not easy, cause the structure members are encoded sequencely, and nested, so it is very hard to code the skip to get the offset of the request byte.

    Anyway, uhmm, to put all extra information in the context is one solution, I can even put the PricingInfo into it, thanks.
  • benoit
    benoit Rennes, France
    Hi,

    Are you sure avoiding the marshaling/un-marshaling in the forwarder worth the added complexity? It sounds like it would be much simpler for your forwarder to actually access the price request and forwarding information structures. You might want to run some performance testing to ensure this is really worth it.

    Cheers,
    Benoit.
  • The forwarder doing a load-balancing job, so it didn't need information in request, but to accelerate I need do a cache, if the request matches in bytes, so I just return it without forward it to a pricer. If I demarshal it in forwarder, I do marshaling twice. It looks like IceStorm, but different is, it will not publish the request to all pricer, but find a less loaded pricer and do the calculation, and I can also cache the result for a while.

    Well, thanks anyway, I think the context might be the good solution.
  • The truth is that the pricing request would be a very big and complex structure, including lot of data.