### Overview of the ACE Network Services

ACE provides a standard library of network services:

Naming Service Time Service Token Service | Server Logging Service Client Logging Service Logging Strategy Service

These services play two roles in ACE:

- They provide reusable components for common distributed system tasks such as logging, naming, locking, and time synchronization.

- They illustrate how to utilize ACE features such as the IPC wrappers, Reactor, Service Configurator, Service Initialization, and Concurrency components.

The heart of the ACE network services is the Service Configurator, which is an object-oriented framework that automates the configuration and reconfiguration of multi-service daemons. All the ACE network services are configured using the Service Configurator. Please refer to the online documentation for more information on installing and testing the ACE network services.

### Overview of Naming Service

A Naming Service associates names with values in a distributed system. Clients can query these values using these names as keys. Such a name-to-value association is called a Name Binding . Name bindings are defined relative to a Naming Context . A naming context is a collection that contains a set of name bindings in which each name is unique. Different names can be bound to the same value in the same or different naming contexts at the same time. There are three types of naming contexts:

1. Process Local Naming Context: Name bindings are accessible from processes with the same name running on the same host.

2. Node Local Naming Context: Name bindings are accessible from all processes running on the same host.

3. Network Local Naming Context: Name bindings are accessible from all processes running on any machine within a (sub)network.

To bind a name is to create a name binding in a given context. Querying a value using a name determines the value associated with the name in a given context. Note that a name is always bound relative to a context. Thus, there are no absolute names.

The following are the key classes in the ACE Naming Service:

- `Class Naming_Context`

  This is the main class ``entry point'' into the Naming Service. It is used both by client processes and by server process. It manages access to the appropriate Name/Binding database (that is the file where Name/Bindings are stored) and it also manages the communication between a client process and the server (by using class Name_Proxy, which is a private member of Naming_Context). If a client process runs on the same host as the server no IPC is necessary because the Naming_Context uses shared memory.

- `Class Name_Acceptor`

  The Name_Acceptor allocates in its handle_input() routine a new instance of class Name_Handler on the heap, and accepts connections into this Name_Handler.

- `Class Name_Handler`

  The class Name_Handler represents the server side of communication between client and server. It interprets incoming requests to the Net_Local namespace and delegates the requests to its own Naming_Context (which is the Net_Local namespace on the current host). For communication it uses the helper classes Name_Request and Name_Reply.

- Dependencies

  The ACE Naming Service uses ACE_WString String classes since it must handle wide character strings in order to support internationalization.

The following describes how to configure the Name_Server server and client test applications.

- Startup configuration

  Configuring a Name_Server server or client requires specifying all or some of the following parameters. These parameters can be passed in to main through command line as follows:

  Option | Description | Default value
  -c <naming context> | Naming Context to use. Can be either "PROC_LOCAL" or "NODE_LOCAL" or "NET_LOCAL" | PROC_LOCAL
  -h <hostname> | Specify the server hostname (needed by Name Server clients for PROC_LOCAL naming context) | ACE_DEFAULT_SERVER_HOST
  -p <nameserver port> | Port number where the server process expects requests | ACE_DEFAULT_SERVER_PORT
  -l <namespace dir> | Directory that holds the NameBinding databases | ACE_DEFAULT_NAMESPACE_DIR
  -P <process name> | Name of the client process | argv[0]
  -s <database name> | Name of the database. NameBindings for the appropriate naming context are stored in file <namespace_dir>/<database name>. | null
  -d <debug> | Turn debugging on/off | 0 (off)
  -T <trace> | Turn tracing on/off | 0 (off)
  -v <verbose> | Turn verbose on/off | 0 (off)

- Examples

  1. Here is what a config file would look like for starting up a server at port 20222 using NET_LOCAL naming context with database called MYDATABSE located in directory /tmp:

         dynamic Naming_Service Service_Object *
           ../lib/netsvcs:_make_ACE_Name_Acceptor()
           "-p 20222 -c NET_LOCAL -l /tmp -s MYDATABASE"

  2. Here is what a config file would look like for starting up a client that connects to a Name Server running on host tango.cs.wustl.edu at port 20222:

         dynamic Naming_Service_Client Service_Object *
           ../lib/netsvcs:_make_Client_Test()
           "-h tango.cs.wustl.edu -p 20222"

  Note:

  - Values for parameters can also be passed in using environment variables. For example, instead of specifying absolute hostname or port numbers in the config file, we can use $HOST and $PORT, respectively, in the file (assuming that these environment variables have been set).

  - If the environment variable LD_LIBRARY_PATH (in the case of UNIX) or PATH (in the case of Win32) contains the path to the shared object files or dll, then the config file can be further simplified. Instead of specifying a path to the shared object or dll, only the name of the shared object or dll would suffice. That is, the Service Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) to look for the shared object files or dlls.

### Overview of Time Service

Time Service provides accurate, fault-tolerant clock synchronization for computers collaborating in local area networks and wide area networks. Synchronized time services are important in distributed systems that require multiple hosts to maintain accurate global time. The architecture of the distributed time service contains the following Time Server, Clerk, and Client components:

- Time Server answers queries about the time made by Clerks.

- Clerk queries one or more Time Servers to determine the correct time, calculates the approximate correct time using one of several distributed time algorithms and updates its own local system time.

- Client uses the global time information maintained by a Clerk to provide consistency with the notion of time used by clients on other hosts.

The following are the key classes in the ACE Time Service:

- `Class TS_Server_Handler`

  TS_Server_Handler represents the server side of communication between clerk and server. It interprets incoming requests for time updates, gets the system time, creates a reply in response to the request and then sends the reply to the clerk from which it received the request. For communication it uses the helper class Time_Request.

- `Class TS_Server_Acceptor`

  TS_Server_Acceptor allocates in its handle_input routine a new instance of class TS_Server_Handler on the heap, and accepts connections into this TS_Server_Handler.

- `Class TS_Clerk_Handler`

  TS_Clerk_Handler represents the clerk side of communication between clerk and server. It generates requests for time updates every timeout period and then sends these requests to all the servers it is connected to asynchronously. It receives the replies to these requests from the servers through its handle_input method and then adjusts the time using the roundtrip estimate. It caches this time, which is subsequently retrieved by TS_Clerk_Processor.

- `Class TS_Clerk_Processor`

  TS_Clerk_Processor creates a new instance of TS_Clerk_Handler for every server connection it needs to create. It periodically calls send_request() of every TS_Clerk_Handler to send a request for time update to all the servers. In the process, it retrieves the latest time cached by each TS_Clerk_Handler and then uses it to compute its notion of the local system time.

- Algorithms

  Currently, updating the system time involves taking the average of all the times received from the servers.

The following is a description of how to configure the Time Server clerk and server services:

- Startup configuration

  Configuring a server requires specifying the port number of the server. This can be specified as a command line argument as follows:

  -p <port number>

  A clerk communicates with one or more server processes. To communicate with the server process, a client needs to know the INET_Addr, where the server offers its service. The configuration parameters namely the server port and server host are passed as command line arguments when starting up the clerk service as follows:

  -h <server host1>:<server port1> -h <server host2>:<server port2> ...

  Note that multiple servers can be specified in this manner for the clerk to connect to when it starts up. The server name and the port number need to be concatenated and separated by a ":". In addition, the timeout value can also be specified as a command line argument as follows:

  -t timeout

  The timeout value specifies the time interval at which the clerk should query the servers for time updates.

  By default a Clerk does a non-blocking connect to a server. This can be overridden and a Clerk can be made to do a blocking connect by using the -b flag.

- Examples

  1. Here is what a config file would look like for starting up a server at port 20202:

         dynamic Time_Service Service_Object *
           ../lib/netsvcs:_make_ACE_TS_Server_Acceptor()
           "-p 20202"

  2. Here is what a config file would look like for starting up a clerk that needs to connect to two servers, one at tango and one at lambada:

         dynamic Time_Server_test Service_Object *
           ../lib/netsvcs:_make_ACE_TS_Clerk_Connector ()
           "-h tango:20202 -h lambada:20202 -t 4"

  Note:

  - These files would vary if the services are run on NT. For example, instead of using *.so, we would have to use *.dll.

  - Values for parameters can also be passed in using environment variables. For example, instead of specifying absolute hostname or port numbers in the config file, we can use $HOST and $PORT, respectively, in the file (assuming that these environment variables have been set).

  - If the environment variable LD_LIBRARY_PATH (in the case of UNIX) or PATH (in the case of Win32) contains the path to the shared object files or dll, then the config file can be further simplified. Instead of specifying a path to the shared object or dll, only the name of the shared object or dll would suffice. That is, the Service Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) to look for the shared object files or dlls.

### Token Service

The ACE Token Service provides local and remote mutexes and readers/writer locks. For information regarding the deadlock detection algorithm, check out ACE_Token_Manager.h. For information about an implementation of the Composite Pattern for Tokens, check out Token_Collection.h. The classes which implement the local and remote synchronization primitives are listed below:

- `ACE_Local_Mutex`

  This class is a more general-purpose synchronization mechanism than SunOS 5.x mutexes. For example, it implements "recursive mutex" semantics, where a thread that owns the token can reacquire it without deadlocking. In addition, threads that are blocked awaiting the token are serviced in strict FIFO order as other threads release the token (SunOS 5.x mutexes don't strictly enforce an acquisition order). Lastly, ACE_Local_Mutex performs deadlock detection on acquire calls.

- `ACE_Remote_Mutex`

  This is the remote equivalent to ACE_Local_Mutex. The Remote_Mutex class offers methods for acquiring, renewing, and releasing a distributed synchronization mutex. Similar to ACE_Local_Mutex, ACE_Remote_Token_Proxy offers recursive acquisition, FIFO waiter ordering, and deadlock detection. It depends on the Token Server for its distributed synchronization semantics.

- `ACE_Local_RLock`

  This class implements the reader interface to canonical readers/writer locks. Multiple readers can hold the lock simultaneously when no writers have the lock. Alternatively, when a writer holds the lock, no other participants (readers or writers) may hold the lock. This class is a more general-purpose synchronization mechanism than SunOS 5.x RLocks. For example, it implements "recursive RLock" semantics, where a thread that owns the token can reacquire it without deadlocking. In addition, threads that are blocked awaiting the token are serviced in strict FIFO order as other threads release the token (SunOS 5.x RLockes don't strictly enforce an acquisition order).

- `ACE_Local_WLock`

  This class implements the writer interface to canonical readers/writer locks. Multiple readers can hold the lock simultaneously when no writers have the lock. Alternatively, when a writer holds the lock, no other participants (readers or writers) may hold the lock. This class is a more general-purpose synchronization mechanism than SunOS 5.x WLock. For example, it implements "recursive WLock" semantics, where a thread that owns the token can reacquire it without deadlocking. In addition, threads that are blocked awaiting the token are serviced in strict FIFO order as other threads release the token (SunOS 5.x WLocks don't strictly enforce an acquisition order).

- `ACE_Remote_RLock`

  This is the remote equivalent to ACE_Local_RLock. Multiple readers can hold the lock simultaneously when no writers have the lock. Alternatively, when a writer holds the lock, no other participants (readers or writers) may hold the lock. ACE_Remote_RLock depends on the ACE Token Server for its distributed synchronization semantics.

- `ACE_Remote_RLock`

  This is the remote equivalent to ACE_Local_WLock.

The Token Server provides distributed mutex and readers/writer lock semantics to the ACE Token library. ACE_Remote_Mutex, ACE_Remote_RLock, and ACE_Remote_WLock, are proxies to the Token Server. The following are the key classes in the ACE Token Server:

- `class Token_Acceptor`

  The Token_Acceptor is a Token_Handler factory. It accepts connections and passes the service responsibilities off to a new Token_Handler.

- `class Token_Handler`

  This class is the main class ``entry point'' of the ACE Token service. It receives token operation requests from remote clients and turns them into calls on local tokens (acquire, release, renew, and remove). In OMG CORBA terminology, it is an ``Object Adapter.'' It also schedules and handles timeouts that are used to support "timed waits." Clients used timed waits to bound the amount of time they block trying to get a token.

The following describes how to configure the Token Server:

- Startup configuration

  The only parameter that the Token Server takes is a listen port number. You can specify a port number by passing a "-p " to the application. This can be done via the svc.conf file.

- Examples

  Here is an example svc.conf entry that dynamically loads the Token Server specifying port number to listen on for client connections:

  ``

              dynamic Token_Service Service_Object *
                ../lib/netsvcs:_make_ACE_Token_Acceptor()
                "-p 10202"

Note:

- These files would vary if the services are run on NT. For example, instead of using *.so, we would have to use *.dll.

- Values for parameters can also be passed in using environment variables. For example, instead of specifying absolute hostname or port numbers in the config file, we can use $HOST and $PORT, respectively, in the file (assuming that these environment variables have been set).

- If the environment variable LD_LIBRARY_PATH (in the case of UNIX) or PATH (in the case of Win32) contains the path to the shared object files or dll, then the config file can be further simplified. Instead of specifying a path to the shared object or dll, only the name of the shared object or dll would suffice. That is, the Service Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) to look for the shared object files or dlls.

### Overview of Server Logging Service

The Server Logging Service provides a concurrent, multi-service daemon that processes logging records received from one or more client hosts simultaneously. The object-oriented design of the Server Logging Service is decomposed into several modular components that perform well-defined tasks.

The following are the key classes in the Server Logging Service:

- `Server_Logging_Handler`

  The Server_Logging_Handler class is a parameterized type that is responsible for processing logging records sent to the Server from participating client hosts. When logging records arrive from the client host associated with a particular Logging Handler object, the handle_input() method of the Server_Logging_Handler class is called which in turn formats and displays the records on one or more output devices (such as the printer, persistent storage, and/or console devices.

- `Server_Logging_Acceptor`

  The class Server_Logging_Acceptor allocates in its handle_input() routine a new instance of class Server_Logging_Handler on the heap, and accepts connections into this Server_Logging_Handler.

The following describes how to configure the Logging Server:

- Startup configuration

  The only parameter that the Logging Server takes is a listen port number. You can specify a port number by passing a "-p " to the application. This can be done via the svc.conf file.

- Examples

  Here is an example svc.conf entry that dynamically loads the Logging Server specifying port number to listen on for client connections:

            dynamic Server_Logging_Service Service_Object *
              ../lib/netsvcs:_make_ACE_Server_Logging_Acceptor()
              "-p 10202"

Note:

- These files would vary if the services are run on NT. For example, instead of using *.so, we would have to use *.dll.

- Values for parameters can also be passed in using environment variables. For example, instead of specifying absolute hostname or port numbers in the config file, we can use $HOST and $PORT, respectively, in the file (assuming that these environment variables have been set).

- If the environment variable LD_LIBRARY_PATH (in the case of UNIX) or PATH (in the case of Win32) contains the path to the shared object files or dll, then the config file can be further simplified. Instead of specifying a path to the shared object or dll, only the name of the shared object or dll would suffice. That is, the Service Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) to look for the shared object files or dlls.

### Overview of Client Logging Service

The Client Logging Service multiplexes messages recevied from different applications to the Server Logging Daemon running on a designated host in a network/internetwork. The following are the key classes in the Client Logging Service:

- `Client_Logging_Handler`

  The Client_Logging_Handler class is a parameterized type that is responsible for setting up a named pipe and using it to communicate with different user processes on the same host. Once logging records arrive from these processes, the handler reads these records in priority order, performs network-byte order conversions on multiple-header fields, and then transmits these records to the Server Logging daemon across the network.

- `Client_Logging_Connector`

  The class Client_Logging_Connector connects to the Server Logging daemon and then in its handle_input() routine it allocates a new instance of the Client_Logging_Handler on the heap.

The following describes how to configure the Logging Client:

- Startup configuration

  Configuring a Logging Client requires specifying all or some of the following parameters. These parameters can be passed in to main through command line as follows:

  Option | Description | Default value
  -h <hostname> | Hostname of the Server Logging Daemon | ACE_DEFAULT_SERVER_HOST
  -p <port number> | Port number of the Server Logging Daemon | ACE_DEFAULT_LOGGING_SERVER_PORT
  -p <rendezvous key> | Rendezvous key used to create named pipe | ACE_DEFAULT_RENDEZVOUS

- Examples

  Here is an example svc.conf entry that dynamically loads the Logging Client specifying host name and port number of the Logging Server:

            dynamic Client_Logging_Service Service_Object *
              ../lib/netsvcs:_make_ACE_Client_Logging_Connector()
              "-h tango.cs.wustl.edu -p 10202"

Note:

- These files would vary if the services are run on NT. For example, instead of using *.so, we would have to use *.dll.

- Values for parameters can also be passed in using environment variables. For example, instead of specifying absolute hostname or port numbers in the config file, we can use $HOST and $PORT, respectively, in the file (assuming that these environment variables have been set).

- If the environment variable LD_LIBRARY_PATH (in the case of UNIX) or PATH (in the case of Win32) contains the path to the shared object files or dll, then the config file can be further simplified. Instead of specifying a path to the shared object or dll, only the name of the shared object or dll would suffice. That is, the Service Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) to look for the shared object files or dlls.

### Overview of Logging Strategy Service

The Logging Strategy Service can be used to control the output of all the network services. It can be invoked with certain flags that determine where the output of all the services should go. The Logging Strategy Service sets the flags in ACE_Log_Msg, which controls all the streams through macros such as ACE_DEBUG, ACE_ERROR, and ACE_ERROR_RETURN. If default behavior is required, the Logging Strategy Service need not be invoked or it can be invoked with no parameters.

The following describes how to configure the Logging Strategy Service:

- Startup configuration

  Here are the command line arguments that can be given to the Logging Strategy Service:

  -f <flag1>|<flag2>|<flag3> (etc...)

  where a flag can be any of the following:

  Flags | Description
  STDERR | Write messages to stderr.
  LOGGER | Write messages to the local client logger deamon.
  OSTREAM | Write messages to the ostream that gets created by specifying a filename (see below)
  VERBOSE | Display messages in a verbose manner
  SILENT | Do not print messages at all

  Note: If more than one flag is specified, the flags need to be 'OR'ed as above syntax shows. Make sure there is no space in between the flag and '|'.

  -s filename

  If the OSTREAM flag is set, this can be used to specify the filename where the output should be directed. Note that if the OSTREAM flag is set and no filename is specified, ACE_DEFAULT_LOGFILE will be used to write the output to.

- Examples:

  Here is an example svc.conf entry that dynamically loads the Logging Strategy Service specifying that the output be sent to STDERR:

            dynamic Logging_Strategy_Service Service_Object *
              ../lib/netsvcs:_make_ACE_Logging_Strategy()
              "-f STDERR"

  1. To direct output only to STDERR, specify command line arguments as:

     "-f STDERR"

  2. To direct output to both STDERR and a file called "mylog", specify command line arguments as:

     "-f STDERR|OSTREAM -s mylog"

  Note:

  - These files would vary if the services are run on NT. For example, instead of using *.so, we would have to use *.dll.

  - Values for parameters can also be passed in using environment variables. For example, instead of specifying absolute hostname or port numbers in the config file, we can use $HOST and $PORT, respectively, in the file (assuming that these environment variables have been set).

  - If the environment variable LD_LIBRARY_PATH (in the case of UNIX) or PATH (in the case of Win32) contains the path to the shared object files or dll, then the config file can be further simplified. Instead of specifying a path to the shared object or dll, only the name of the shared object or dll would suffice. That is, the Service Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) to look for the shared object files or dlls.

Back to the ACE home page.