CHASM

Crytpograph-Hash-Algorithm-Secured Mirroring

The Refractions of Design: Part III

Both upstream and downstream can have multiple connections concurrently, at a high level this is accomplished using async calls. Each connection instantiates a connection chain, which is functionally a state machine where each state is a message in the protocol. A message framework provides the structure for sending and receiving. It consists of two classes send_message and recv_message that take a state object, either a send_state or recv_state, respectively. The state object handles preparing and processing the message by implementing the operations used by send_message and recv_message.

class send_state
{
    ...
    // send operations
    virtual void prepare(connection_ptr conn, chasm::buffer& msg)
            throw (std::bad_alloc);
    virtual recv_state_ptr next_state() const;
    ...
};

Although briefly more than one state per connection will exist, usually there will only be one at any given point in time. The ephemeral nature of the states is accomplished through pointers and callbacks. A state is instantiated as a shared pointer and then started, shortly after that an async call will be made that will unwind the stack and the calling object will be destroyed. Callbacks provide a mechanism for keeping objects alive. The state becomes the callback through the use of bind and the this pointer. Following is a snippet of code demonstrating the concepts used:

void v0 :: send_message :: start()
{
    ...
    m_state_obj->prepare(m_conn, m_msg);
    ...
    send();
}

void v0 :: send_message :: send() const
{
    boost::asio::async_write(*m_conn->_socket, boost::asio::buffer(m_msg),
                             boost::bind(&v0::send_message::goto_next_state,
                                         shared_from_this(),
                                         boost::asio::placeholders::error));
}

void v0 :: send_message :: goto_next_state(...) const
{
    ...
    v0::recv_state_ptr state_obj = m_state_obj->next_state();
    if (state_obj.get())
    {
        boost::shared_ptr<v0::recv_message>
            rm(new v0::recv_message(m_conn, state_obj));
        rm->start();
    }
    ...
}

...

-mfm

Copyright © 2010 Robert Escriva ¦ Powered by Firmant