Persistent connections

  • Overview

    • owserver protocol

      The owserver protocol is a well defined network protocol for client requests of information from owserver

      • tcp transport

      • 24 byte header

      • variable data

      • owserver-owserver special loop suppression tags

    • Stateless design

      • The original protocol is stateless

      • Each request for information is sent on a new tcp connection

      • The connection is closed by the server after the response is sent

    • Persistence enhancement

      • Improve performance by leaving connection open to accept subsequsnt requests

      • Optional persistence with fallback stateless connection if persistence will not be granted

  • Server design

    • Safe fallback

      If a persistent connection cannot be granted, the request is handled as a non-persistent connection, and closed after the respone is sent.

      owserver only accepts a persistent request if

    1. It is requested

    2. The resource limits aren't exceeded

  • Resource limits

    There are 2 limits (tunable from the command line) on

  1. the total number of connections

  2. the number of connections before the shorter time limit is enforced

  • Timeouts

    Timeouts are the period an inactive connection will be kept open. Each new request restarts the timer.

    There are 2 time limits (tunable from the command line) on

    1. Minimum persistent connection inactivity

    2. Maximum persistent connection inactivity

  • Design

    • owserver uses a separate thread for each connection

    • "select" is used for the blocked read with a timeout

    • mutex locked counters are used for total counts for resource limits

    • each response has the persistent flag set if the connection will be kept open

  • Client design

    • Optional persistence

      • The client need not request persistence if

        • it is a single-shot request

        • it doesn't want to keep track of connection information

      • The server need not grant persistence if

        • it's resource limits are exceeded

        • it doesn't support persistent connections (older designs, non thread compilation)

      • The client should test the response to see if persistence was granted after every response.

    • Non-guaranteed persistence

      • There is no assurance that the persistent connection will be kept open by the server.

      • Clients should reopen a new connection if a persistent connection was refused and retry the request.

      • The new connection will work as a single-shot connection at the very least.

    • Multithreaded clients

      • owfs, owftpd, owhttpd, owserver are examples

      • cannot use the same persistent connection from multiple threads simultaneously

      • programs linking libow are protected

        • only one persistent connection per owserver allowed

        • other threads will use non-persistent connections.

  • Known problems

    • Backwards compatibility

      STATUS THEORETICAL

      All old versions (pre-persistent) of owserver SHOULD ignore and not set the persistent flag, but this hasn't been exaustively verified.

    • Resued handles

      STATUS THEORETICAL

      It is possible that a discarded port on the server could be reused by another client connection and also be the original persistent connection. The client would have to have the same IP address, and thus shouldn't allow this conflict, but owserver cannot verify this.

    Implementation

    owserver header has the following format (converted to network order for transmission, and back on arrival) 

    /* message to owserver */
    struct server_msg <<
    int32_t version;
    int32_t payload;
    int32_t type;
    int32_t sg;
    int32_t size;
    int32_t offset;
    >>;

    /* message to client */
    struct client_msg <<
    int32_t version;
    int32_t payload;
    int32_t ret;
    int32_t sg;
    int32_t size;
    int32_t offset;
    >>;

     In the flag word, sg, bit 2 (mask 0x00000004) is

    • ONE if persistence it requested/granted
    • ZERO ifpersistence is not-requested/not-granted