aboutsummaryrefslogblamecommitdiff
path: root/include/salticidae/network.h
blob: 93b5766cfdb4e0cc2edaded9c433ba4c7b6f4356 (plain) (tree)


























                                                                                  
                             
























































                                                                                



                                                                                









                                        

                                                                                
                           





                                                      


                                                                      





















                                                                   

                               



                                                                                









                                               
                                                           
                                                     





















































                                                                               
                                                                                 























                                                                              
                         










                                                                                
                                       



                                               


                                                      



                                        







                                                            
                                     

                                                  


                                                                      






























                                                                                    

                                                                       

















































                                                                                             
                                      








































































                                                                                          

                                                        
                                   




































































































                                                                                            
                                                            




















































                                                                                
/**
 * Copyright (c) 2018 Cornell University.
 *
 * Author: Ted Yin <tederminant@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef _SALTICIDAE_NETWORK_H
#define _SALTICIDAE_NETWORK_H

#include "salticidae/event.h"
#include "salticidae/netaddr.h"
#include "salticidae/msg.h"
#include "salticidae/conn.h"

namespace salticidae {

/** Network of nodes who can send async messages.  */
template<typename MsgType>
class MsgNetwork: public ConnPool {
    public:
    class Conn: public ConnPool::Conn {
        enum MsgState {
            HEADER,
            PAYLOAD
        };
        MsgType msg;
        MsgState msg_state;
        MsgNetwork *mn;

        protected:
        mutable size_t nsent;
        mutable size_t nrecv;

        public:
        friend MsgNetwork;
        Conn(MsgNetwork *mn): msg_state(HEADER), mn(mn), nsent(0), nrecv(0) {}
        size_t get_nsent() const { return nsent; }
        size_t get_nrecv() const { return nrecv; }
        void clear_nsent() const { nsent = 0; }
        void clear_nrecv() const { nrecv = 0; }

        protected:
        void on_read() override;
        void on_setup() override {}
        void on_teardown() override {}
    };

    using conn_t = RcObj<Conn>;
    using msg_callback_t = std::function<void(const MsgType &msg, conn_t conn)>;
    class msg_stat_by_opcode_t:
            public std::unordered_map<typename MsgType::opcode_t,
                                        std::pair<uint32_t, size_t>> {
        public:
        void add(const MsgType &msg) {
            auto &p = this->operator[](msg.get_opcode());
            p.first++;
            p.second += msg.get_length();
        }
    };

    private:
    std::unordered_map<typename MsgType::opcode_t,
                        msg_callback_t> handler_map;

    protected:
    mutable msg_stat_by_opcode_t sent_by_opcode;
    mutable msg_stat_by_opcode_t recv_by_opcode;

    ConnPool::conn_t create_conn() override { return (new Conn(this))->self(); }

    public:
    MsgNetwork(const EventContext &eb,
            int max_listen_backlog,
            double try_conn_delay,
            double conn_server_timeout,
            size_t seg_buff_size):
        ConnPool(eb, max_listen_backlog,
                    try_conn_delay,
                    conn_server_timeout,
                    seg_buff_size) {}

    void reg_handler(typename MsgType::opcode_t opcode, msg_callback_t handler);
    void send_msg(const MsgType &msg, conn_t conn);
    using ConnPool::listen;
    msg_stat_by_opcode_t &get_sent_by_opcode() const {
        return sent_by_opcode;
    }
    msg_stat_by_opcode_t &get_recv_by_opcode() const {
        return recv_by_opcode;
    }
    conn_t create_conn(const NetAddr &addr) {
        return static_pointer_cast<Conn>(ConnPool::create_conn(addr));
    }
};

/** Simple network that handles client-server requests. */
template<typename MsgType>
class ClientNetwork: public MsgNetwork<MsgType> {
    using MsgNet = MsgNetwork<MsgType>;
    std::unordered_map<NetAddr, typename MsgNet::conn_t> addr2conn;

    public:
    class Conn: public MsgNet::Conn {
        ClientNetwork *cn;

        pub