int main () { std::atomic <uint16_t> response_count (0); paxos::server::callback_type callback = [& response_count](int64_t, std::string const & workload) -> std::string { ++response_count; return "bar"; }; paxos::configuration configuration; configuration.set_strategy_factory (new test_strategy_factory (configuration.durable_storage ())); paxos::server server1 ("127.0.0.1", 1337, callback); paxos::server server2 ("127.0.0.1", 1338, callback); paxos::server server3 ("127.0.0.1", 1339, callback, configuration); paxos::client client; server1.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); server2.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); server3.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); client.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); /*! This would be retried and shouldn't cause any troubles. */ PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); PAXOS_ASSERT_EQ (response_count, 2); PAXOS_INFO ("test succeeded"); }
int main () { paxos::configuration configuration1; paxos::configuration configuration2; paxos::configuration configuration3; configuration1.durable_storage ().set_history_size (5); configuration2.durable_storage ().set_history_size (5); configuration3.durable_storage ().set_history_size (5); paxos::server::callback_type callback = []( int64_t promise_id, std::string const & workload) -> std::string { return "bar"; }; paxos::client client; client.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); paxos::server server1 ("127.0.0.1", 1337, callback, configuration1); paxos::server server2 ("127.0.0.1", 1338, callback, configuration2); server1.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); server2.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); { paxos::server server3 ("127.0.0.1", 1339, callback, configuration3); server3.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); /*! Issue 10 calls, so we can verify that the lowest proposal id is in fact 10. */ for (size_t i = 0; i < 15; ++i) { PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); } PAXOS_ASSERT_EQ (configuration1.durable_storage ().lowest_proposal_id (), 11); PAXOS_ASSERT_EQ (configuration2.durable_storage ().lowest_proposal_id (), 11); PAXOS_ASSERT_EQ (configuration3.durable_storage ().lowest_proposal_id (), 11); } /*! Now, since one host in our quorum is currently down, logs should *not* be cleaned up further than the proposal that has been previously accepted by that host. */ for (size_t i = 0; i < 30; ++i) { PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); } PAXOS_ASSERT_GE (configuration1.durable_storage ().lowest_proposal_id (), 15); PAXOS_ASSERT_GE (configuration2.durable_storage ().lowest_proposal_id (), 15); PAXOS_ASSERT_EQ (configuration3.durable_storage ().lowest_proposal_id (), 11); boost::this_thread::sleep ( boost::posix_time::milliseconds ( paxos::configuration ().timeout ())); { /*! And after our server is back online, the history can be cleared again. */ paxos::server server3 ("127.0.0.1", 1339, callback, configuration3); server3.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); for (size_t i = 0; i < 15; ++i) { PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); } PAXOS_ASSERT_EQ (configuration1.durable_storage ().lowest_proposal_id (), 56); PAXOS_ASSERT_EQ (configuration2.durable_storage ().lowest_proposal_id (), 56); PAXOS_ASSERT_EQ (configuration3.durable_storage ().lowest_proposal_id (), 56); } PAXOS_INFO ("test succeeded"); }
int main () { std::map <int64_t, uint16_t> responses; /*! Synchronizes access to responses */ boost::mutex mutex; paxos::configuration configuration1; paxos::configuration configuration2; paxos::configuration configuration3; /*! Note that the configuration objects below outlive the server objects declared later in the test, thus providing semi-durable storage. */ configuration1.set_durable_storage ( new paxos::durable::heap ()); configuration2.set_durable_storage ( new paxos::durable::heap ()); configuration3.set_durable_storage ( new paxos::durable::heap ()); paxos::server::callback_type callback = [& responses, & mutex]( int64_t promise_id, std::string const & workload) -> std::string { boost::mutex::scoped_lock lock (mutex); if (responses.find (promise_id) == responses.end ()) { responses[promise_id] = 1; } else { responses[promise_id]++; } PAXOS_ASSERT (responses[promise_id] <= 3); return "bar"; }; paxos::client client; client.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); { paxos::server server1 ("127.0.0.1", 1337, callback, configuration1); server1.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); { paxos::server server2 ("127.0.0.1", 1338, callback, configuration2); server2.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); { paxos::server server3 ("127.0.0.1", 1339, callback, configuration3); server3.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); PAXOS_ASSERT_EQ (all_responses_equal (responses, 3), true); } PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); PAXOS_ASSERT_EQ (all_responses_equal (responses, 3), false); } PAXOS_ASSERT_THROW (client.send ("foo").get (), paxos::exception::no_majority); } /*! Note that we're re-adding servers in reverse order here; this is to ensure that server3 doesn't become our leader while it's lagging behind. */ paxos::server server3 ("127.0.0.1", 1339, callback, configuration3); server3.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); PAXOS_ASSERT_THROW (client.send ("foo").get (), paxos::exception::no_majority); paxos::server server2 ("127.0.0.1", 1338, callback, configuration2); server2.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); boost::this_thread::sleep ( boost::posix_time::milliseconds ( paxos::configuration ().timeout ())); PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); paxos::server server1 ("127.0.0.1", 1337, callback, configuration1); server1.add ({{"127.0.0.1", 1337}, {"127.0.0.1", 1338}, {"127.0.0.1", 1339}}); boost::this_thread::sleep ( boost::posix_time::milliseconds ( paxos::configuration ().timeout ())); do { PAXOS_ASSERT_EQ (client.send ("foo").get (), "bar"); } while (all_responses_equal (responses, 3) == false); PAXOS_INFO ("test succeeded"); }
int main(int argc, char **argv) { int listenfd; struct sockaddr_in servaddr; int bind_status; int listen_status; struct sockaddr_in cliaddr; socklen_t clilen; int connfd; pid_t childpid; char buffer[MAX_LINE + 1]; time_t current_time; int write_status; int read_status; int close_status; /*Check for correct argument length*/ if (argc != 1) { printf("usage: tcpserver\n"); return(errno); } /*Define socket file descriptor*/ listenfd = socket(AF_INET, SOCK_STREAM, 0); if(listenfd < 0) { printf("socket error\n"); return(errno); } /*Initialize server socket*/ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); /*Bind address to socket*/ bind_status = bind(listenfd, (SA*) &servaddr, sizeof(servaddr)); if(bind_status < 0) { printf("bind error\n"); return(errno); } /*Listen for clients*/ listen_status = listen(listenfd, LISTENQ); if(listen_status < 0) { printf("listen error\n"); return(errno); } for( ; ; ) { /*Accept a client connection*/ connfd = accept(listenfd, (SA*) &cliaddr, &clilen); childpid = fork(); if(childpid < 0) { printf("fork error\n"); return(errno); } if(childpid == 0) { /*Close listening connection*/ close_status = close(listenfd); if(close_status < 0) { printf("close error\n"); } /* process the request */ /*server(connfd);*/ /*server2(connfd, (SA*) &cliaddr, clilen);*/ server3(connfd); exit(0); } /*Close client connection*/ close_status = close(connfd); if(close_status < 0) { printf("close error\n"); } /*Clear buffer*/ bzero(buffer, sizeof(buffer)); } return(0); }