Important: The information in this document is obsolete and should not be used for new development.
Improving Performance
The following suggestions for improving performance were drawn up with servers in mind; however, if your application needs to handle multiple connection requests, you might find the section "Streamlining Endpoint Creation" useful. For additional information on handling throughput to improve performance, see the chapter "Advanced Topics".Streamlining Endpoint Creation
The time required to create and open an endpoint can delay connection set-up time. This can adversely affect servers, especially HTTP servers, since they must manage high connection turnover rates. To handle this problem, follow these guidelines:
- Preallocate endpoints
Preallocate a pool of open, unbound endpoints into an endpoint cache. When a connection is requested (you receive a
T_LISTEN
event), you can dequeue an endpoint from this cache and pass it to the functionOTAccept
.Using this method, the only time you have to wait for an endpoint to be created is if the queue is empty, when you must allocate an additional block of endpoints.
- Recycle endpoints
You can use an endpoint-cache to recycle endpoints when your connection is closed. Rather than call the function
OTCloseProvider
each time a connection terminates, cache the unbound endpoint. This keeps it available for a subsequent open request.To use this method, unbind the endpoint upon receipt of the
T_DISCONNECT
event. Then, when the notifier receives theT_UNBINDCOMPLETE
event, queue that endpoint into your endpoint cache. Optionally, to save memory, you can deallocate the endpoint when the endpoint cache reaches some predetermined limit.- Create clone configurations
Another way to speed up endpoint creation is to create a prototype configuration structure with the function
OTCreateConfiguration
. Then, use theOTCloneConfiguration
function to pass the configuration structure to the functionOTOpenEndpoint
. The call toOTCloneConfiguration
is about five times faster than that to theOTCreateConfiguration
function.
Handling Dead Clients
A properly designed server should be prepared to handle what happens when a remote client unexpectedly disappears. This problem is further aggravated when the link has been flow-controlled. For example:
You can solve this problem by flushing the stream before requesting the disconnection. The best way to do this is to send the
- You are transmitting a large amount of data to a client.
- Your transport provider enters a flow-control state.
- The client crashes or becomes unreachable.
- After a timeout, your server decides to force a disconnect from that client and issues a disconnect request.
- However the
T_DISCONNECT
event is subject to flow control, which causes your link to hang.
I_FLUSH
command to the stream head using theOTIoctl
function. For example:
#include <stropts.h> /* check to see if you are already disconnected */ error = OTIoctl(ep, I_FLUSH, (void*) FLUSHRW); if error OTUnbind(ep) ..... MyNotifyProc (... void* the Param) { case kStreamIoctlEvent /* flush is complete */ (void) OTSndDisconnect (ep, NULL);/* safe to disconnect */ break; }This will result in your notifier receiving allT_MEMORYRELEASED
events for any outstanding send calls that acknowledge sends. You should then attempt to send the disconnection request.Shutting Down Servers
To shut down an Open Transport network server properly, you need to:
- Make sure that all network and I/O operations have either completed or aborted.
- Flush any flow-controlled data streams with the
I_FLUSH
command. See "Handling Dead Clients" for detailed information.- Unbind and close all endpoints.
- Cancel any outstanding deferred tasks with the function
OTDestroyDeferredTask
.- Release any
OTBuffer
structures with the functionOTReleaseBuffer
.- Dispose of any unused configuration structures with the function
OTDestroyConfiguration
.
Subtopics
- Streamlining Endpoint Creation
- Handling Dead Clients
- Shutting Down Servers