Archived

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

calling Ice interface functions locally

Is there a way to call Ice interface functions locally? a typical signature:
void fx(const Ice::Current&current) ;

has an Ice::Current parameter, which I have no way to construct.

Otherwise, I would need to get access to an ObjectAdapter from the
Ice::CommunicatorPtr &communicator

I see methods to create an ObjectAdapter, but no methods to get a pointer to an existing adapter.

I need to execute a function like this from an icebox service constructor:
Bt::ScheduledActivityPrx OssServiceControlImpl::createScheduledActivity(const Ice::Current &current)
{
	//create an SA Interface object and add it to the adapter

	Ice::ObjectPtr pObject = new ScheduledActivityImpl();
	return Bt::ScheduledActivityPrx::uncheckedCast(current.adapter->addWithUUID(pObject));
}

the issue is I dont have the adapter


thanks
Rich

Comments

  • matthew
    matthew NL, Canada
    What do you mean by locally? Do you mean you want to directly on a servant? if so, then you could pass null to the method and deal with that in the servant upcall. Otherwise, I would recommend calling on the servant through a proxy. That will ensure that the current is suitably provided. If you are worried about performance, you probably don't need to be. If you call on a servant through a proxy which is created on the same communicator then you'll use a special optimized call path. Look up collocation optimization in the Ice manual.
  • Yes I mean directly on a servant. either that, or I need a way to get an object adapter by name
    I need to create an object in the icebox service start method where I only have a communicator. The issue is below from the previous post:
    return Bt::ScheduledActivityPrx::uncheckedCast(current.adapter->addWithUUID(pObject));
    

    I need the Context to get the adapter, or a way in the Communicator to get the already created adapter. Is there a reason you cant get the list of adapters in the communicator? This is a hierarchy issue where I dont want to pass the adapter down multiple levels if its not needed.

    thanks
    Rich
  • bernard
    bernard Jupiter, FL
    Hi Rich,

    There is no operation on the Communicator to find an object adapter by name; while the communicator maintains internally a map name to object-adapter, so far there was no need to expose such "find" feature.

    But let's step back for a moment, as you may be missing an important detail here. The communicator parameter you get in your IceBox service constructor (presumably called by your C entry point function) is the IceBox server's own communicator: see "C++ Service" in http://www.zeroc.com/doc/Ice-3.4.1/manual/IceBox.44.3.html

    It's not the communicator of another service, and I doubt you want to get an object adapter associated with this communicator.

    You should probably postpone this proxy creation until start is called on your service and you have the service's communicator. Are you configuring IceBox to share the same communicator between services? By default, each IceBox service gets its own communicator.

    Best regards,
    Bernard
  • Bernard,

    the call stack I am in is this:
    >	OSSd.dll!OssServiceControlImpl::OssServiceControlImpl(const IceInternal::Handle<Ice::Communicator> & communicator={...})  Line 29 + 0x99 bytes	C++
     	OSSd.dll!IceBoxServiceTemplate<OssServiceControlImpl>::start(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & name="Oss", const IceInternal::Handle<Ice::Communicator> & communicator={...}, const std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & args=[0]())  Line 55 + 0x3a bytes	C++
     	iceboxd.exe!IceBox::ServiceManagerI::start(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & service="Oss", const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & entryPoint="C:\Dev\CORE4\Services\lib\Oss:create", const std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & args=[1]("--Ice.Config=c:\\Dev\\CORE4\\Services\\OSS/config/db/node/servers/OssIceBox/config/config_Oss"))  Line 674 + 0x3d bytes	C++
     	iceboxd.exe!IceBox::ServiceManagerI::start()  Line 480 + 0x56 bytes	C++
     	iceboxd.exe!IceBox::IceBoxService::start(int argc=1, char * * argv=0x0033cac8, int & status=1)  Line 105 + 0x12 bytes	C++
     	ice34d.dll!Ice::Service::run(int & argc=1, char * * argv=0x0033cac8, const Ice::InitializationData & initData={...})  Line 960 + 0x1d bytes	C++
     	ice34d.dll!Ice::Service::main(int & argc=1, char * * argv=0x0033cac8, const Ice::InitializationData & initializationData={...})  Line 840 + 0x14 bytes	C++
     	ice34d.dll!Ice::Service::main(std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & args=[2]("C:\Program Files (x86)\ZeroC\Ice-3.4.1\bin\iceboxd.exe","--Ice.Config=c:\\Dev\\CORE4\\Services\\OSS/config/db/node/servers/OssIceBox/config/config"), const Ice::InitializationData & initData={...})  Line 873 + 0x14 bytes	C++
     	ice34d.dll!Ice::Service::main(int & argc=2, wchar_t * * argv=0x0033c6b8, const Ice::InitializationData & initializationData={...})  Line 862 + 0x3d bytes	C++
     	iceboxd.exe!wmain(int argc=2, wchar_t * * argv=0x0033c6b8)  Line 157 + 0x1a bytes	C++
     	iceboxd.exe!__tmainCRTStartup()  Line 583 + 0x19 bytes	C
     	iceboxd.exe!wmainCRTStartup()  Line 403	C
    

    So I am where you were suggesting that I do this, I just dont have a Context Pointer at that point, which is needed to call my function:
    Bt::ScheduledActivityPrx OssServiceControlImpl::createScheduledActivity(const Ice::Current &current)
    

    If I do this inline instead of by calling the interface function, I need to be able to get the adapter I created several levels up in the call stack (and object hierarchy). If I have to pass this, I could , but its only needed once. I am only passing the communicator down the hierarchy right now. Thus the question about how to find adapters. Are you suggesting that I create a new second adapter for this? All other external calls via proxy are going to use the original adapter located by current.adapter

    thanks
    Rich
  • bernard
    bernard Jupiter, FL
    Hi Rich,

    There are several options, for example:

    - you could pass this object adapter instead of the communicator down your call stack (and retrieve the communicator associated with the adapter with ObjectAdapter::getCommunicator), and manufacture an Ice::Current object when you call your OssServiceControl servant

    - you could pass a proxy to the OssServiceControl object down your call stack, and then no need to worry about Ice::Current and object adapters (that's probably cleaner)

    - you could keep a reference to the object adapter in your servant:
    Bt::ScheduledActivityPrx OssServiceControlImpl::createScheduledActivity(const Ice::Current &current)
    {
    	// current may be empty, as this function may be called directly
            // and not through a proxy
    
    	Ice::ObjectPtr pObject = new ScheduledActivityImpl;
    	return Bt::ScheduledActivityPrx::uncheckedCast(_adapter->addWithUUID(pObject));
    }
    
    One potential benefit of this approach is that you could use different object adapters for the OssServiceControl object and the ScheduledActivity objects.

    - [more advanced] if OssServiceControl is an administration object for your services, it could make sense to register it as a facet to the Ice.Admin object. Beware that with IceBox, you need the IceBox server's communicator to get hold of the Ice.Admin proxy (see Communicator::getAdmin). Then other parts of your code would just need this proxy (or the IceBox server communicator) and the associated Ice.Admin facet name to retrieve this OssServiceControl proxy.

    Best regards,
    Bernard
  • Bernard,

    thanks for the answer. that seems to clear up most things for me.

    Rich