So, by now we have implemented our Acceptor Service: known how to initialize, remove, suspend and resume our service. We have the server daemon set up to run to accept requests. The only thing that is left is the client_handler. We need to declare and define the Client_Handler object. We will use the same Client_Handler.h and Client_Handler.cpp that we used in our ACE Tutorial 005.
With this, we are done with everything that we want to get our Acceptor Service dynamically configurable in addition to the actual functionality of the Acceptor.
To compile, we can use the same Makefile that we used previously and make appropriate changes for the new files that we added. You could use this Makefile
Now, lets compile it and be all set to configure our Acceptor Service. Let us run our server to start acting as a daemon and accept requests.
$ ./server
Obviously, we will want to load our service dynamically and see if our Acceptor Service is running as we want it to. For this, we need to make an entry in the svc.conf file.
The Service Configurator framework reads the entries in the svc.conf file in the working directory by default. According to the entries in the svc.con file, the framework does the needful. You could use a different name for the file like server.conf but in that case, we need to explicitly specify to the application the configuration file that has to be read using the -ORBSvcconf option.
Coming back to where we were, now we want to make an entry in this svc.conf file to load our service. I will show you the general format for this entry and then we will make our entry.
A dynamic service could be initialized as:dynamic service_name type_of_service * location_of_shared_lib:name_of_object "parameters"and a static service is initialized as:
static service_name "parameters_sent_to_service_object"
Lets start making our entry. The first keyword specifies if this is a dynamic service or a static one. Since we want our service to be a dynamically configurable one, the first parameter in our entry will be dynamic. The next parameter is the name of the service that we want to be loaded. This is the same name that we specified in the ACE_STATIC_SVC_DEFINE macro. Since our service name is Acceptor_Service, that becomes the second parameter of our entry. The next argument is the type of the service .. as we know already, there are two options: Stream or Service_Object. And, we declared our service to be a Service_Object in the ACE_STATIC_SVC_DEFINE macro. So, that becomes the next parameter. The next entry is the location of the shared library which has our service and that is Acceptor_Server according to our Makefile. The next parameter is the name of the object and finally the list of parameters that we want to pass to our service. So, we are now erady to make our entry in the svc.conf file to initialize our service.
dynamic Acceptor_Service Service_Object * ./Acceptor_Server:_make_Acceptor_Service () ""
Now, we want to reconfigure so that our service will be initialized. This could be done by sending a signal which would be received eventually by the Reactor listening for requests and it would invoke the ACE_Service::reconfigure () method which does the reconfiguration of the services.
$ kill -1 PID_of_our_serverNow, that we know how to initialize our service and actually initialized the service .. we could check if our service is working good. Ofcourse, the debug statements we left in the init method would help .. but to double check !! For this purpose, we can use the simple client which we used in our ACE Tutorial 005. Just compile the client.cpp using this Makefile and run it. You can see the responses from the service.
Now, we can check if we can suspend and resume and finally remove the service. The entries for these functionalities are very simple unlike the initialization entry.
$ suspend Acceptor_Service
$ resume Acceptor_Service
$ remove Acceptor_Service
Lets first suspend the service by commenting out the entry for the initialization and making the new entry for suspension in the svc.conf file. Now, send a signal as before. The Reactor will receive this event and suspend the service. Just to double check, you could run our client again and see the response.
Now, to resume the service, the procedure is the same. Comment out other entries and make the entry for the resumption of the service. And finally, send a signal. Again, you could run the client and see what is happening. But, even before running the client, you must have noticed that as soon as you resumed the service, you saw some response from the Acceptor_Service. This is because, as I explained before, the Reactor will queue the request when the service is in suspension mode and send the service the queued requests as and when it is active again.
Finally, lets remove our service.
So, now we know how to implement a dynamically configurable service and how to dynamically configure the service.