Archived

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

Question about AMI (C++)

Hello,
I am trying to understand Ice and the underlying architecture.

I have a question about AMI: starting from the callback example I'm trying to modify it in order to use the AMI. I want the callback responses managed asyncronously.
My first modification of this project, before using AMI, asks a query in a database and receives the result with the callback message.

In the slice file, I put the keywork ["ami"] before the callback function: is it correct?

Do I go wrong if I write the implementation of the AMI's abstract callback class in the Client.cpp?
Is still correct if I leave the definition of the callback function (now is callback_async()) in the Client.cpp or it needs to be put in the interface's file?

Is the ice_response() a function that only tells if the AMI callback works right or not?

Reading the posts about AMI, I've understood that AMI is a way to have the replies from the server managed asynchronously, and not the invocations from the client. Is that right?

In order to have a communication completely asyncronous, should I use both AMD and AMI in the slice definition?
I looked into the chat example included in the 4th newsletter, that has been a great resource.

I would appreciate a lot any help in the following matter


With my very best regards



Alberto


Alberto

Comments

  • It's not entirely clear to me what you want to achieve. Do you want to invoke the database query (from client to server) asynchronously? Or do you want to send a callback from server to client asynchronously? (An example showing what you want to do would be helpful.)

    In general, AMI allows the client to regain the thread of control before a remote invocation completes. If you have

    interface DB {
    Results sendQuery(string query);
    };

    and it takes a while for sendQuery() to do its job, you can add an ["ami"] directive to the operation. Then the client can invoke sendQuery() asynchronously and regain the thread of control while sendQuery() is still running in the server. When the query has completed in the server, the client gets the ice_response() or ice_exception() callback on the callback object it passed when it invoked the operation. To the server, that's completely transparent--the server can't tell whether the client invoked the operation synchronously or asynchronously.

    AMD is normally used only if you have long-running or blocking operations and want to prevent too many clients from tying up all available threads in the server.

    Have a look at the async chapter in the documention. It contains a nice example for the motivation for asynch invocation and dispatch.

    Cheers,

    Michi.
  • Dear Michi,
    thanks a lot for your reply, and, especially for your explanation

    At the moment, with the modification of the Callback example I'm able to invoke a database query and receive the result with the callback function.
    My intention is to have a method to invoke several queries and receive the results asynchronously, and I thought the best way is to use the AMI.

    Here you will find attached the project.

    Following your example, where should I put the result of the query? in the ice_response() ? or in another function?


    Thanks again


    Sincerely



    Alberto
  • You are using an explicit callback function in your Slice definitions. But the whole point of AMI is that, by using AMI, you avoid having to define such a callback function. Instead, you can define the operation as a normal twoway function and still call it asynchronously.

    Please do have a look at Section 31.3.1 of the manual, which explains this.

    Cheers,

    Michi.
  • Hello Michi,
    I have followed your instructions step-by-step, and the chapter 31.3 of the manual, and now here is my test project nearly completed.

    I receive now only one compilation error, in the server side, which is:
    error C2259: 'AMISqlI' : cannot instantiate abstract class


    I would appreciate a lot if you could have a very quick look at my project, just to let me know what the cause of this error is.


    Thank you very much in advance.



    Best regards



    Alberto
  • benoit
    benoit Rennes, France
    AMI is a client side only construct. You don't have to change the implementation of the servant in the server to use AMI. So the implementation of your sendQuery() method in AMISqlI should looke like the following:
    std::string
    AMISqlI::sendQuery(const std::string& query, const Ice::Current&)
    {
        std::string result;
    
        // ... perform the query ...
    
        return result; // Return the result.
    }
    

    You're getting a compilation error because you don't define this method which is defined as pure virtual in the Demo::AMISql servant base class.

    Hope this helps!

    Cheers,
    Benoit.
  • Hello Benoit,
    thank you very much! You have been really kind, now I do not receive any more errors while compiling.


    I have the client that gets stuck, without showing anything on the console: it happens where the twoway proxy is defined.

    What does it depend on? Do you think there is something wrong in the config file?



    Cheers



    Alberto
  • benoit
    benoit Rennes, France
    Hi,

    I'm afraid looking deeper into this is out of the scope of the free support we can provide on the forums. If you want us to help you with this matter, we can provide you some consulting services, please contact us at info@zeroc.com if that's the case.

    Cheers,
    Benoit.
  • Hello Benoit,
    I hope you will excuse me, I recognize that my questions were going too deep for a free support.


    I found out that the client gets stuck suddenly before showing the menu (without showing any error message), when I do a down-cast with a "checked cast"; otherwise, if I do it with an "unchecked cast" I can view the menu and digit my query but the problem persists and now I receive this error message:
    "Ice::ConnectionRefusedException connection refused: WSAECONNREFUSED".

    What do you think could be the problem? Do you have any suggestions?



    Thank you in advance


    Regards


    Alberto
  • mes
    mes California
    Hi,

    Please refer to this FAQ entry.

    Take care,
    - Mark
  • Thank you Mark.

    As far as the AMI part is concerned, now everything of my project is working properly.

    As you surely have noticed, I'm a newbie, and I've often found often some difficulties at the beginning when programming with ICE, doubts solved thanks to you and your colleagues.

    Now I want to add an AMD part, and I've already read all the posts that deal with it (and the AMD part in the manual).

    I need my server to serve multiple clients in the case they need to operate with long-running or blocking operations: for this simple example, just for learning purposes, the client run a sendQuery_async (through the AMI) and I want the server to send the response with the AMD.

    I have not very clear what should be the implementation of the callback with the AMD in this simple example where I use a single function.
    Is this class a sort of the AMI callback class, mirrored in the server?

    Shall I leave the implementation of the AMI part or should I modify it?


    Can they coexist with such a simple operation?



    Thank in advance


    Cheers


    Alberto