Archived

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

Is there a AMD demo project?

I just change printer example to use AMI/AMD,

interface Printer
{
["ami","amd"] void printString(string s,out string reply);
};

When use AMI it works, but use AMD following the guide from ICE manual, client program report :
printer failed: .\Connection.cpp:208: Ice::CommunicatorDestroyedException:
communicator object destroyed

server side code:
class Job : public IceUtil::Shared
{
public:
Job(const AMD_Printer_printStringPtr &,const ::std::string& );
void execute();
private:
bool setReply();
AMD_Printer_printStringPtr _cb;
string _s;
};
typedef IceUtil::Handle<Job> JobPtr;


Job::Job(const AMD_Printer_printStringPtr & cb,const ::std::string& s):_cb(cb), _s(s)
{
}

bool Job::setReply()
{
_s.append(" welcome to AMD!");
return true;
}

void Job::execute()
{
if(!setReply())
{
return;
}
_cb->ice_response(_s);
}


class PrinterI : virtual public Printer,virtual public IceUtil::Mutex
{
public:
virtual void printString_async(const AMD_Printer_printStringPtr &, const ::std::string&, const Ice::Current &);
private:
::std::list<JobPtr> _jobs;
};

void PrinterI::printString_async(const AMD_Printer_printStringPtr & cb, const ::std::string& s, const Ice::Current &)
{
IceUtil::Mutex::Lock sync(*this);
JobPtr job = new Job(cb, s);
_jobs.push_back(job);
}

And I think AMD do not affect client code, so the client is the same code using AMI.

client code:
ic = Ice::initialize(argc, argv);
Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -p 10000");
PrinterPrx printer = PrinterPrx::checkedCast(base);
if (!printer)
throw "Invalid proxy";

AMI_Printer_printStringPtr cb = new AMI_Printer_printStringI;
printer->printString_async(cb, "Scott");



Is there something wrong in the code? Maybe I can fix the problem by myself if I can get a AMD demo project, but I can't find it in demos shifted with ICE.

Comments

  • mes
    mes California
    Hi,

    Sorry, we don't currently provide an example that demonstrates AMD, although several of the Ice tests make use of AMD. For example, see the code in test/Ice/operations.

    I suspect the reason your client receives a CommunicatorDestroyedException is because your client is not waiting for the AMI request to complete before it destroys its communicator. However, without seeing the complete source code, it's impossible for us to know for sure.

    Take care,
    - Mark
  • Thank you, Mark

    So whether server side use AMD or not, it do not affect client side(sychronize call or AMI), right? That means after deploy the client product, I can change the way server works without update the client side.
  • This is correct, it doesn't matter to the client if the server uses AMD or regular dispatch, and it dosn't matter to the server if the client uses AMI or regular invocations.
  • I know the reason cause AMD client failed. In the ICE manual it mentioned "the response thread" but have no code about it, just push "job" into a job list, so I added a work thread read "job" out and execute, and client side wait for the reply before exit main thread. Finally it works.

    By the way, would you please add response thread code in the ICE manual in future, or provide a AMD demo? I think many beginner may make same mistake like me.

    Thanks for you help!:)
  • Hello wwwtiger,Can you show me the sample code about the question you fix the error. I raise same error with you in this example.
    We hope the manual next version can provide an example code for AMD :confused:
  • matthew
    matthew NL, Canada
    Hello wwwtiger,Can you show me the sample code about the question you fix the error. I raise same error with you in this example.
    We hope the manual next version can provide an example code for AMD :confused:

    What you are likely doing is calling an AMI method, and not waiting for a response before your client terminates. For example:
    //slice
    interface Foo
    {
       ["ami"] void bar();
    }
    
    //C++
    int
    main(int argc, char** argv)
    {
        ...
        FooPrx foo = ...;
    
        AMI_Foo_barPtr cb = new AMI_Foo_barI;
        foo->bar_async(cb);
        communicator->destroy();
        return EXIT_SUCCESS;
    }
    

    This example would cause the above problem in most cases because main doesn't wait for the callback to be actually called before destroying the communicator.

    Regards, Matthew
  • Sorry for my not clear description.
    I had test the ami sample as manual , It is work fine. my question is about the amd. i do a sample it use amd ,like wwwtiger's code ,it build ok but when i call the amd method in client , client and server will no response. and when i press ctrl+c in client side, it show these message:\Connection.cpp:202: Ice::CommunicatorDestroyedException:communicator object destroyed.as wwwtiger said that maybe program no thread read "job" out and execute. as follow code:
    ...
    IceUtil::Mutex::Lock sync(*this);
    JobPtr job = new Job(cb, s);
    _jobs.push_back(job);

    it add a new job into a queue,but i can't find some code that read the job in manual.

    if we must add some code that will new some thread to read out the job and run it? if yes, can you show me these code ? thank you.
  • mes
    mes California
    The example in demo/IceUtil/workqueue shows one way of structuring a work queue using the threading and synchronization classes provided with Ice.

    Take care,
    - Mark
  • I just add a Job thread, and start it on main function

    class JobThread : public IceUtil::Thread
    {
    virtual void run()
    {
    while(1)
    {
    _jobMutex.lock();

    if(_jobs.size()!=0)
    {
    JobPtr firstJob=(JobPtr)_jobs.front();
    _jobs.pop_front();
    firstJob->execute();
    }
    _jobMutex.unlock();
    Sleep(100);
    }
    }
    };

    ====
    //Start job
    IceUtil::ThreadPtr t = new JobThread;
    IceUtil::ThreadControl tc = t->start(); // Start it



    Have a nice day!
  • Hi,wwwtiger,Thanks for your help,.

    but i am confused that why ice run time not to implement like AMI?(AMI will auto new a thread to wait for the response when call the ami asyn call). Because i think if done it and it will can make good use of the server's threadpool advantage to finish these job . but now if these code is must been added manual ,I think I maybe will make mistake and is not effective if i don't take care .if AMD only provide the routine of asyn call? for example: callback class and asyn function. but the job queue and executed thread we must add it manual?
  • benoit
    benoit Rennes, France
    If you want the Ice server thread pool to do all the job, don't use AMD ;) It's important to understand that AMD and AMI are different concepts and therefore their implementation is totally different.

    With AMI, you make asynchronous invocations. You invoke on an object and the invocation will return as soon as the request has been sent over the wire. The calling thread doesn't have to wait for the answer, instead, when the answer is available you'll get a callback through the AMI callback object. Note also that AMI doesn't create any new threads to wait for the answer (it's the Ice client thread pool which is taking care of reading answers from client requests and eventually call on AMI callbacks).

    With AMD, you asynchronously dispatch method invocations. The implementation of a method can release the dispatch thread whenever it wants and send the answer of the method invocation latter from another thread. It's up to you to decide when to send the answer:
    • You might want to do what wwwtiger is doing, i.e.: queue job items that are executed by another thread and send the answer of the invocation when the job item execution completes.
    • You might also want to make an AMI call on an object and and send the answer for the AMD invocation when you receive the answer of the AMI call.
    • You might want to wait for a resource to become available without holding the dispatch thread.
    And I'm sure there's many more use cases!

    Benoit.
  • Recently,I devot all my time to learn ICE and like it more and more. However, I am often baffled by some concepts, such as AMI\AMD. I just feel strange why not give plenty of UML diagrams in the doucument,which can definitely explain the details more clearly .

    So far as this thread, I will feel life easier as a ICE beginner if you can give us a campact and whole printer example to demonstrate the usage of AMI\AMD. It must be easy to you, but It can give me, a newbie , a comprehensive concepts about it. I read those examples in Test/Operations, but, frankly speaking, not like them and lost in them.

    But anyway, thank your execellent work. I just wish to master it as soon as possible.


    Best regards
  • marc
    marc Florida
    The next issue of Connections will have an article about the use of AMI/AMD.