Skip to content

An I/O task system written in modern C++ that implements the Leader/Followers pattern and uses libev as event loop.

License

Notifications You must be signed in to change notification settings

Horizonzhou/libtasks

 
 

Repository files navigation

libtasks

Overview

libtasks is an I/O task system written in modern C++ that implements the Leader/Followers pattern and uses libev as event loop. It allows for writing event based applications. Network as well as disk I/O operations are supported.

Leader/Followers Pattern

The Leader/Followers pattern was published by Douglas C. Schmidt, Carlos O’Ryan, Michael Kircher and Irfan Pyarali back in 2000.

The idea is to allow one thread at a time – the leader – to wait for an event to occur on a set of I/O handles. Meanwhile, other threads – the followers – can queue up waiting their turn to become the leader. After the current leader thread demultiplexes an event from the I/O handle set, it promotes a follower thread to become the new leader and then dispatches the event to a designated event handler, which processes the event. At this point, the former leader and the new leader thread can execute concurrently. In detail: multiple former leader threads can process events concurrently while the current leader thread waits on the handle set. After its event processing completes, an idle follower thread waits its turn to become the leader.

The figure below illustrates the states and the valid transitions in the Leader/Followers pattern.

Use cases

libtasks supports the uwsgi protocol as well as thrift. The uwsgi protocol is supported by web servers like nginx or cherokee to create high performance web application backends.

The following things are possible at the moment:

  • Implement all kinds of io tasks that use file descriptors, like high performance tcp servers

  • Implement high performance web application backends using the uwsgi protocol and high scale web server front ends like nginx.

  • Implement thrift servers using HTTP transport over uwsgi

  • Implement HTTP clients

Documentation

The code documentation can be found at https://adtechlabs.github.io/doc/libtasks.

Building

To build libtasks you will need cmake.

$ git clone ...
$ cd libtasks
$ mkdir build
$ cd build
$ cmake <options> ..
$ make
$ sudo make test
$ sudo make install

Note: To run the tests you need to have nginx installed.

The following cmake options are possible at the moment:

  • -DCMAKE_BUILD_TYPE= - if type is "Debug" the library will be build with debug logging enabled. Set it to "Doc" to generate the code documentation (make doc). Default is "Release".
  • -DDISABLE_TESTS= - if option is "y" or "Y" the tests will not be build. Default is N.
  • -DWITH_EXAMPLES= - if option is "y" or "Y" the examples will be built too. Default is N.
  • -DWITH_PROFILER= - if option is "y" or "Y" the examples will be build with profiling support. Default is N.
  • -DNO_DBG_SYMBOLS= - if option is "y" or "Y" no debug symols will be added to the binary.

Examples

An HTTP client

using namespace tasks::net;

// Create a handler for the HTTP response
class test_handler : public http_response_handler {
public:
    bool handle_response(std::shared_ptr<http_response> response) {
        std::cout << "Got status " << response->status() << std::endl;
        if (response->content_length()) {
            std::cout << "Content:" << std::endl << response->content_p() << std::endl;
        }
        return false;
    }
};

// Send a request
http_sender<test_handler> sender;
auto request = std::make_shared<http_request>("www.google.com", "/");
sender.send(request);

A thrift server with HTTP/uwsgi transport

Consider you want to write a service that looks up information for a given IP address. Look at the ip_service_server example for the details like the thrift IDL.

using namespace tasks;
using namespace tasks::net;

// We need a handler class that does the actual information lookup.
class ip_service : public uwsgi_thrift_handler<IpServiceIf> {
public:
    void lookup(response_type& result, const int32_t ipv4, const ipv6_type& ipv6) {
        key_value_type kv;
        id_name_type val;
        kv.key.id = 1;
        val.id = 123456;
        kv.values.push_back(val);    
        result.key_values.push_back(kv);
    }
};

// Now we can setup the server
dispatcher::instance()->start();
dispatcher::instance()->add_task(new acceptor<uwsgi_thrift_processor<IpServiceProcessor,
                                                                     ip_service>>(12345));
dispatcher::instance()->join();

About

An I/O task system written in modern C++ that implements the Leader/Followers pattern and uses libev as event loop.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 86.8%
  • CMake 6.6%
  • Nginx 3.5%
  • Perl 2.2%
  • Thrift 0.5%
  • Gnuplot 0.2%
  • Other 0.2%