TEST(ConsumerStateTable, set_del)
{
    clearDB();

    /* Prepare producer */
    int index = 0;
    string tableName = "UT_REDIS_THREAD_" + to_string(index);
    DBConnector db(TEST_VIEW, "localhost", 6379, 0);
    ProducerStateTable p(&db, tableName);
    string key = "TheKey";
    int maxNumOfFields = 2;

    /* Set operation */
    {
        vector<FieldValueTuple> fields;
        for (int j = 0; j < maxNumOfFields; j++)
        {
            FieldValueTuple t(field(j), value(j));
            fields.push_back(t);
        }
        p.set(key, fields);
    }

    /* Del operation */
    p.del(key);

    /* Prepare consumer */
    ConsumerStateTable c(&db, tableName);
    Select cs;
    Selectable *selectcs;
    cs.addSelectable(&c);
    int tmpfd;

    /* First pop operation */
    {
        int ret = cs.select(&selectcs, &tmpfd);
        EXPECT_TRUE(ret == Select::OBJECT);
        KeyOpFieldsValuesTuple kco;
        c.pop(kco);
        EXPECT_TRUE(kfvKey(kco) == key);
        EXPECT_TRUE(kfvOp(kco) == "DEL");

        auto fvs = kfvFieldsValues(kco);
        EXPECT_EQ(fvs.size(), 0U);
    }

    /* Second select operation */
    {
        int ret = cs.select(&selectcs, &tmpfd, 1000);
        EXPECT_TRUE(ret == Select::TIMEOUT);
    }
}
Exemple #2
0
[[ noreturn ]] void Logger::settingThread()
{
    Select select;
    DBConnector db(LOGLEVEL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
    std::vector<std::shared_ptr<ConsumerStateTable>> selectables(m_settingChangeObservers.size());

    for (const auto& i : m_settingChangeObservers)
    {
        std::shared_ptr<ConsumerStateTable> table = std::make_shared<ConsumerStateTable>(&db, i.first);
        selectables.push_back(table);
        select.addSelectable(table.get());
    }

    while(true)
    {
        Selectable *selectable = nullptr;

        int ret = select.select(&selectable);

        if (ret == Select::ERROR)
        {
            SWSS_LOG_NOTICE("%s select error %s", __PRETTY_FUNCTION__, strerror(errno));
            continue;
        }

        KeyOpFieldsValuesTuple koValues;
        dynamic_cast<ConsumerStateTable *>(selectable)->pop(koValues);
        std::string key = kfvKey(koValues), op = kfvOp(koValues);

        if ((op != SET_COMMAND) || (m_settingChangeObservers.find(key) == m_settingChangeObservers.end()))
        {
            continue;
        }

        auto values = kfvFieldsValues(koValues);
        for (const auto& i : values)
        {
            const std::string &field = fvField(i), &value = fvValue(i);
            if ((field == DAEMON_LOGLEVEL) && (value != m_currentPrios[key]))
            {
                m_currentPrios[key] = value;
                m_settingChangeObservers[key].first(key, value);
            }
            else if ((field == DAEMON_LOGOUTPUT) && (value != m_currentOutputs[key]))
            {
                m_currentOutputs[key] = value;
                m_settingChangeObservers[key].second(key, value);
            }

            break;
        }
    }
}
Exemple #3
0
int main()
{
	int size = 8;
	int a1[] = {4, 8, 2, 1, 3, 5, 6, 7};
	Select s;
	for (int i = 0; i < size; i++)
	{
	  	assert(s.select(a1, size, i) == i + 1);
	}

	size = 5;
	int a2[] = {5, 4, 3, 2, 1};
	for (int i = 0; i < size; i++)
	{
	  	assert(s.select(a2, size, i) == i + 1);
	}

	size = 10;
	int a3[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	for (int i = 0; i < size; i++)
	{
	  	assert(s.select(a3, size, i) == i + 1);
	}

	size = 1;
	int a5[] = { 1 };
	for (int i = 0; i < size; i++)
	{
	  	assert(s.select(a5, size, i) == i + 1);
	}

	size = 2;
	int a6[] = {2, 1};
	for (int i = 0; i < size; i++)
	{
	  	assert(s.select(a6, size, i) == i + 1);
	}

	return 0;
}
void test_select_random_access(const Select& select, bit_vector::size_type args, bit_vector::size_type times)
{
    typedef bit_vector::size_type size_type;
    const int s = 20;
    const uint64_t mask = (1<<s)-1;
    int_vector<64> rands(1<<s ,0);
    util::set_random_bits(rands, 17);
    util::all_elements_mod(rands, args);
    for (size_type i=0; i<rands.size(); ++i)
        rands[i] = rands[i]+1;
    size_type cnt=0;
    write_R_output("select","random access","begin",times,cnt);
    for (size_type i=0; i<times; ++i) {
        cnt += select.select(rands[ i&mask ]);
    }
    write_R_output("select","random access","end",times,cnt);
}
Exemple #5
0
int main(int argc, char **argv)
{
    swss::Logger::linkToDbNative("fpmsyncd");
    DBConnector db(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
    RedisPipeline pipeline(&db);
    RouteSync sync(&pipeline);

    NetDispatcher::getInstance().registerMessageHandler(RTM_NEWROUTE, &sync);
    NetDispatcher::getInstance().registerMessageHandler(RTM_DELROUTE, &sync);

    while (1)
    {
        try
        {
            FpmLink fpm;
            Select s;

            cout << "Waiting for connection..." << endl;
            fpm.accept();
            cout << "Connected!" << endl;

            s.addSelectable(&fpm);
            while (true)
            {
                Selectable *temps;
                int tempfd;
                /* Reading FPM messages forever (and calling "readMe" to read them) */
                s.select(&temps, &tempfd);
                pipeline.flush();
                SWSS_LOG_DEBUG("Pipeline flushed");
            }
        }
        catch (FpmLink::FpmConnectionClosedException &e)
        {
            cout << "Connection lost, reconnecting..." << endl;
        }
        catch (const exception& e)
        {
            cout << "Exception \"" << e.what() << "\" had been thrown in deamon" << endl;
            return 0;
        }
    }

    return 1;
}
static void consumerWorker(int index)
{
    string tableName = "UT_REDIS_THREAD_" + to_string(index);
    DBConnector db(TEST_VIEW, "localhost", 6379, 0);
    ConsumerStateTable c(&db, tableName);
    Select cs;
    Selectable *selectcs;
    int tmpfd;
    int numberOfKeysSet = 0;
    int numberOfKeyDeleted = 0;
    int ret, i = 0;
    KeyOpFieldsValuesTuple kco;

    cs.addSelectable(&c);
    while ((ret = cs.select(&selectcs, &tmpfd)) == Select::OBJECT)
    {
        c.pop(kco);
        if (kfvOp(kco) == "SET")
        {
            numberOfKeysSet++;
            validateFields(kfvKey(kco), kfvFieldsValues(kco));
        } else if (kfvOp(kco) == "DEL")
        {
            numberOfKeyDeleted++;
        }

        if ((i++ % 100) == 0)
            cout << "-" << flush;

        if (numberOfKeyDeleted == NUMBER_OF_OPS)
            break;
    }

    EXPECT_TRUE(numberOfKeysSet <= numberOfKeyDeleted);
    EXPECT_EQ(ret, Selectable::DATA);
}
TEST(ConsumerStateTable, multitable)
{
    DBConnector db(TEST_VIEW, "localhost", 6379, 0);
    ConsumerStateTable *consumers[NUMBER_OF_THREADS];
    thread *producerThreads[NUMBER_OF_THREADS];
    KeyOpFieldsValuesTuple kco;
    Select cs;
    int numberOfKeysSet = 0;
    int numberOfKeyDeleted = 0;
    int ret = 0, i;

    clearDB();

    cout << "Starting " << NUMBER_OF_THREADS*2 << " producers and consumers on redis, using single thread for consumers and thread per producer" << endl;

    /* Starting the consumer before the producer */
    for (i = 0; i < NUMBER_OF_THREADS; i++)
    {
        consumers[i] = new ConsumerStateTable(&db, string("UT_REDIS_THREAD_") +
                                         to_string(i));
        producerThreads[i] = new thread(producerWorker, i);
    }

    for (i = 0; i < NUMBER_OF_THREADS; i++)
        cs.addSelectable(consumers[i]);

    while (1)
    {
        Selectable *is;
        int fd;

        ret = cs.select(&is, &fd);
        EXPECT_EQ(ret, Select::OBJECT);

        ((ConsumerStateTable *)is)->pop(kco);
        if (kfvOp(kco) == "SET")
        {
            numberOfKeysSet++;
            validateFields(kfvKey(kco), kfvFieldsValues(kco));
        } else if (kfvOp(kco) == "DEL")
        {
            numberOfKeyDeleted++;
            if ((numberOfKeyDeleted % 100) == 0)
                cout << "-" << flush;
        }

        if (numberOfKeyDeleted == NUMBER_OF_OPS * NUMBER_OF_THREADS)
            break;
    }

    EXPECT_TRUE(numberOfKeysSet <= numberOfKeyDeleted);

    /* Making sure threads stops execution */
    for (i = 0; i < NUMBER_OF_THREADS; i++)
    {
        producerThreads[i]->join();
        delete consumers[i];
        delete producerThreads[i];
    }

    cout << endl << "Done." << endl;
}
TEST(ConsumerStateTable, singlethread)
{
    clearDB();

    int index = 0;
    string tableName = "UT_REDIS_THREAD_" + to_string(index);
    DBConnector db(TEST_VIEW, "localhost", 6379, 0);
    ProducerStateTable p(&db, tableName);

    for (int i = 0; i < NUMBER_OF_OPS; i++)
    {
        vector<FieldValueTuple> fields;
        int maxNumOfFields = getMaxFields(i);
        for (int j = 0; j < maxNumOfFields; j++)
        {
            FieldValueTuple t(field(j), value(j));
            fields.push_back(t);
        }
        if ((i % 100) == 0)
            cout << "+" << flush;

        p.set(key(i), fields);
    }

    ConsumerStateTable c(&db, tableName);
    Select cs;
    Selectable *selectcs;
    int tmpfd;
    int ret, i = 0;
    KeyOpFieldsValuesTuple kco;

    cs.addSelectable(&c);
    int numberOfKeysSet = 0;
    while ((ret = cs.select(&selectcs, &tmpfd)) == Select::OBJECT)
    {
        c.pop(kco);
        EXPECT_TRUE(kfvOp(kco) == "SET");
        numberOfKeysSet++;
        validateFields(kfvKey(kco), kfvFieldsValues(kco));

        if ((i++ % 100) == 0)
            cout << "-" << flush;

        if (numberOfKeysSet == NUMBER_OF_OPS)
            break;
    }

    for (i = 0; i < NUMBER_OF_OPS; i++)
    {
        p.del(key(i));
        if ((i % 100) == 0)
            cout << "+" << flush;
    }

    int numberOfKeyDeleted = 0;
    while ((ret = cs.select(&selectcs, &tmpfd)) == Select::OBJECT)
    {
        c.pop(kco);
        EXPECT_TRUE(kfvOp(kco) == "DEL");
        numberOfKeyDeleted++;

        if ((i++ % 100) == 0)
            cout << "-" << flush;

        if (numberOfKeyDeleted == NUMBER_OF_OPS)
            break;
    }

    EXPECT_TRUE(numberOfKeysSet <= numberOfKeyDeleted);
    EXPECT_EQ(ret, Selectable::DATA);

    cout << "Done. Waiting for all job to finish " << NUMBER_OF_OPS << " jobs." << endl;

    cout << endl << "Done." << endl;
}
TEST(ConsumerStateTable, double_set)
{
    clearDB();

    /* Prepare producer */
    int index = 0;
    string tableName = "UT_REDIS_THREAD_" + to_string(index);
    DBConnector db(TEST_VIEW, "localhost", 6379, 0);
    ProducerStateTable p(&db, tableName);
    string key = "TheKey";
    int maxNumOfFields = 2;

    /* First set operation */
    {
        vector<FieldValueTuple> fields;
        for (int j = 0; j < maxNumOfFields; j++)
        {
            FieldValueTuple t(field(j), value(j));
            fields.push_back(t);
        }
        p.set(key, fields);
    }

    /* Second set operation */
    {
        vector<FieldValueTuple> fields;
        for (int j = 0; j < maxNumOfFields * 2; j += 2)
        {
            FieldValueTuple t(field(j), value(j));
            fields.push_back(t);
        }
        p.set(key, fields);
    }

    /* Prepare consumer */
    ConsumerStateTable c(&db, tableName);
    Select cs;
    Selectable *selectcs;
    cs.addSelectable(&c);
    int tmpfd;

    /* First pop operation */
    {
        int ret = cs.select(&selectcs, &tmpfd);
        EXPECT_TRUE(ret == Select::OBJECT);
        KeyOpFieldsValuesTuple kco;
        c.pop(kco);
        EXPECT_TRUE(kfvKey(kco) == key);
        EXPECT_TRUE(kfvOp(kco) == "SET");

        auto fvs = kfvFieldsValues(kco);
        EXPECT_EQ(fvs.size(), (unsigned int)(maxNumOfFields + maxNumOfFields/2));

        map<string, string> mm;
        for (auto fv: fvs)
        {
            mm[fvField(fv)] = fvValue(fv);
        }

        for (int j = 0; j < maxNumOfFields; j++)
        {
            EXPECT_EQ(mm[field(j)], value(j));
        }
        for (int j = 0; j < maxNumOfFields * 2; j += 2)
        {
            EXPECT_EQ(mm[field(j)], value(j));
        }
    }

    /* Second select operation */
    {
        int ret = cs.select(&selectcs, &tmpfd, 1000);
        EXPECT_TRUE(ret == Select::TIMEOUT);
    }
}
Exemple #10
0
            /** accepts and keeps track of connections. reads data
              from connected peers and notifies through virtual methods
              if packets can be deserialized 
             \param tls use GnuTLS for encryption 
             \param port listen for incoming connections at this port
             \param maxPeers maximum number of connected peers */
            void serve(bool tls, int port, int maxPeers) {
                if (tls)
                    sock.reset(new TLSSocket());
                else
                    sock.reset(new Socket());
                sock->setNonBlocking();
                sock->bind(port);
                sock->listen(maxPeers);
                Select select;
                /* Wait for a peer, send data and term */
                while (!closed)
                {
                    select.reset();
                    if (peers.size() < maxPeers)
                        select.input(sock->getFd());
                    for (typename Peers::iterator i = peers.begin(); i != peers.end(); i++) {
                        select.input((*i)->getFd());
                    }
                    if (select.select(100) == -1)
                        continue;
                    if (select.canRead(sock->getFd()) 
                            && peers.size() < maxPeers) {
                        try {
                            Socket* csock = sock->accept();

                            if (tls)  {
                                boost::threadpool::schedule(pool, 
                                        boost::bind(&Server::handshake, this, csock));
                            } else {
                                peers.push_back(boost::shared_ptr<PeerT>(new PeerT()));
                                csock->setNonBlocking();
                                peers.back()->setup(csock);
                                onJoin(*peers.back());

                            }
                        } catch (SocketExcept& e) {
                            std::cerr << e.what() << std::endl;
                        }
                    }
                    if (tls)  {
                        Socket* sock = NULL;
                        socketsReady.try_pop_front(sock);
                        if (sock) {
                            sock->setNonBlocking();
                            peers.push_back(boost::shared_ptr<PeerT>(new PeerT()));
                            peers.back()->setup(sock);
                            onJoin(*peers.back());
                        }
                    }
                    for (size_t i = 0; i < peers.size(); i++) {
                        boost::shared_ptr<PeerT>& p = peers[i];
                        if (select.canRead(p->getFd()))
                            p->onInput();
                        while (p->hasPacket()) {
                            onPacket(*p);
                        }
                    }
                    // collect dead peers
                    size_t count = peers.size();
                    for (size_t i = 0; i < count; ) {
                        if (!peers[i]->isActive()) {
                            onLeave(*peers[i]);

                            peers[i] = peers[peers.size() - 1];
                            count--;
                        } else
                            i++;
                    }
                    if (count < peers.size()) {
                        peers.resize(count);
                    }

                }
            }