Skip to content

cpv-project/cpv-framework

Repository files navigation

C++ web framework based on seastar framework

Codacy Badge Build Status license GitHub release

cpv framework is a web framework written in c++ based on seastar framework, it focus on high performance and modular design.

seastar framework is an application framework that use the share nothing programming model, which isolate resources explicitly for each cpu core. cpv framework use this model too, a cpv application will initialize services on each cpu core, execute them on each cpu core and avoid sharing data between cpu cores, you don't need thread locks or atomic variables in cpv application because all code will be thread safe by design.

In addition, cpv framework avoid memory copies by using reference counted slice of string (cpv::SharedString) and scattered message (cpv::Packet) everywhere. You can get a slice of url path, query parameter, http header, and body content of request from the original packet without allocate a new string and copy them (there few cases require copy such as http header value splited in two packets, or query parameter different after decoded), and you can construct a scattered message contains multiple non-continuous fragments as http response body (based on posix vectored I/O api).

For more features, see the feature list and documents below.

Features

  • Isolate resources explicitly between cpu cores
  • Avoid memory copies by using cpv::SharedString and cpv::Packet everywhere
  • Future promise based asynchronous interface
  • Dependency injection container
  • Modular design
    • Modules decide what to do when application start and stop
    • Modules register services to dependency injection container and retrive services from it
  • Http server
    • Supports Http 1.0/1.1 (based on http-parser)
    • Supports pipeline
    • Supports chaining multiple request handlers (middleware style)
    • Supports full and wildcard url routing (by using routing handler)
    • Provide stream interface for request body and response body
    • Provide static file handler, supports pre compressed gzip, bytes range, If-Modified-Since detection and lru memory cache
  • Serialization
    • Provide json serializer and deserializer (based on sajson)
    • Provide http form serializer and deserializer

You can also check the roadmap to see which features will be added in the next release.

Getting Started

Install cpv framework

If you're using ubuntu 18.04, you can install cpv framework from PPA, this is the easiest way:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:compiv/cpv-project
sudo apt-get update
sudo apt-get install cpvframework

In addition, you need gcc-9 to compile cpv application.

sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get install g++-9

If you're using other linux distribution, you can install from source:

# please ensure seastar framework is installed
# please ensure `pkg-config --cflags seastar` works
# please ensure `pkg-config --libs seastar` works

mkdir -p build/cpvframework-custom
cd build/cpvframework-custom
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
	-DCMAKE_C_COMPILER=gcc-9 \
	-DCMAKE_CXX_COMPILER=g++-9 \
	../../src
make V=1
make install V=1

If you're using windows or macosx, you can use docker with ubuntu 18.04 image because seastar framework is basiclly linux only.

Write a hello world application

This is the source code of a hello world cpv application, it's same as examples/HelloWorld/Main.cpp:

#include <seastar/core/app-template.hh>
#include <CPVFramework/Application/Application.hpp>
#include <CPVFramework/Application/Modules/LoggingModule.hpp>
#include <CPVFramework/Application/Modules/HttpServerModule.hpp>
#include <CPVFramework/Application/Modules/HttpServerRoutingModule.hpp>
#include <CPVFramework/Http/HttpResponseExtensions.hpp>

int main(int argc, char** argv) {
	seastar::app_template app;
	app.run(argc, argv, [] {
		cpv::Application application;
		application.add<cpv::LoggingModule>();
		application.add<cpv::HttpServerModule>([] (auto& module) {
			module.getConfig().setListenAddresses({ "0.0.0.0:8000", "127.0.0.1:8001" });
		});
		application.add<cpv::HttpServerRoutingModule>([] (auto& module) {
			module.route(cpv::constants::GET, "/", [] (cpv::HttpContext& context) {
				return cpv::extensions::reply(context.getResponse(), "Hello World!");
			});
		});
		return application.runForever();
	});
	return 0;
}

It creates a cpv application, add 3 modules, route GET "/" to a custom handle function which replies "Hello World!" and run the cpv application on seastar framework forever (until Ctrl+C pressed).

Compile and execute the hello world application

Now you can compile the hello world application:

g++-9 $(pkg-config --cflags seastar) \
	$(pkg-config --cflags cpvframework) \
	hello.cpp \
	$(pkg-config --libs seastar) \
	$(pkg-config --libs cpvframework)

And execute it with:

# --reactor-backend epoll is recommended because it's stable but not required
./a.out --reactor-backend epoll

It will initialize services and handle requests like this graphic describe (assume it used 2 cpu cores):

example-app-design

Finally you can test the application with curl:

curl -v https://localhost:8000

Documents

Examples

Benchmark results

To see history results please check the change log of the wiki page.

Running Tests

Please check tests/travis_run_tests.sh for how to setup a environment for testing and run the tests.

Contribution

You should follow these rules when contributing code, pull request or patch is welcome.

  • Use tabs instead of spaces
  • For class names, use camel case and start with a upper case (e.g. SomeClass)
  • For function names, use camel case and start with a lower case (e.g. someFunction)
  • For local variable names, use camel case and start with a lower case (e.g. someInt)
  • For global variable names, use camel case and start with a upper case (e.g. SomeGlobalValue)
  • For class member names, use camel case and start with a lower case and ends with _ (e.g. someMember_)
  • Write comments for every public class and function, keep the code as simple as possible

License

LICENSE: MIT LICENSE
Copyright © 2018-2020 303248153@github
If you have any license issue please contact [email protected].