Giter VIP home page Giter VIP logo

trantor's People

Contributors

an-tao avatar antores avatar bansan85 avatar bertrandd avatar codebobo avatar fantasy-peak avatar greisby avatar gschmottlach-xse avatar hks2002 avatar hwc0919 avatar ihmc3jn09hk avatar interfector18 avatar irineu avatar ivanka2012 avatar jgilje avatar ken-matsui avatar kn71026 avatar luk1337 avatar marty1885 avatar mwx2006 avatar neilcook avatar ostropik avatar ototot avatar pkovacs avatar tao-an avatar taoan avatar vayudev avatar vedranmiletic avatar vladlenpopolitov avatar wanggao1990 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

trantor's Issues

Trantor works with mtls?

Hi,

I'm making some tests with tls connection and i would like to check the performance and verify if this framework works with mutual tls connection. If yes, is there kind of example of code?

I've checked the examples and class TcpClient::enableSSL without success.

Best regards,
Irineu A.

aarch64: Static_assert fails

Hello,
It compiles fine on x86_64 but fail static_assert on aarch64 (Nvidia Xavier).

ubuntu@ubuntu-desktop:~/dev/trantor/build$ make
Scanning dependencies of target trantor
[  4%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/AsyncFileLogger.cc.o
[  8%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/ConcurrentTaskQueue.cc.o
[ 12%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Date.cc.o
[ 16%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/LogStream.cc.o
/home/ubuntu/dev/trantor/trantor/utils/LogStream.cc: In member function ‘void trantor::LogStream::staticCheck()’:
/home/ubuntu/dev/trantor/trantor/utils/LogStream.cc:107:5: error: static assertion failed
     static_assert(kMaxNumericSize - 10 >
     ^~~~~~~~~~~~~
CMakeFiles/trantor.dir/build.make:101: recipe for target 'CMakeFiles/trantor.dir/trantor/utils/LogStream.cc.o' failed
make[2]: *** [CMakeFiles/trantor.dir/trantor/utils/LogStream.cc.o] Error 1
CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/trantor.dir/all' failed
make[1]: *** [CMakeFiles/trantor.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

I originally thought it was cross-compilation issue but same error happens when compiling directly on Nvidia Xavier board.

使用下面的代码,可以把编译器降低到c++11

//from https://github.com/zhaoyaogit/rpclib
#ifndef MAKE_UNIQUE_HPP
#define MAKE_UNIQUE_HPP

#include

namespace std {
// Default behaviour is to assume C++11, overriding RPCLIB_CXX_STANDARD can use
// newer standards:
#if RPCLIB_CXX_STANDARD >= 14

using std::make_unique;

#else

template<typename T, typename... Ts>
std::unique_ptr make_unique(Ts&&... params)
{
return std::unique_ptr(new T(std::forward(params)...));
}

#endif

}

#endif /* end of include guard: MAKE_UNIQUE_HPP */

botan build error in macos

cd build
sudo make && sudo make install
shell: /bin/bash --noprofile --norc -e -o pipefail {0}
[ 1%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/AsyncFileLogger.cc.o
[ 2%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/ConcurrentTaskQueue.cc.o
[ 3%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Date.cc.o
[ 4%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/LogStream.cc.o
[ 5%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Logger.cc.o
[ 6%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/MsgBuffer.cc.o
[ 7%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/SerialTaskQueue.cc.o
[ 8%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/TimingWheel.cc.o
[ 9%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Utilities.cc.o
[ 10%] Building CXX object CMakeFiles/trantor.dir/trantor/net/EventLoop.cc.o
[ 11%] Building CXX object CMakeFiles/trantor.dir/trantor/net/EventLoopThread.cc.o
[ 13%] Building CXX object CMakeFiles/trantor.dir/trantor/net/EventLoopThreadPool.cc.o
[ 14%] Building CXX object CMakeFiles/trantor.dir/trantor/net/InetAddress.cc.o
[ 15%] Building CXX object CMakeFiles/trantor.dir/trantor/net/TcpClient.cc.o
[ 16%] Building CXX object CMakeFiles/trantor.dir/trantor/net/TcpServer.cc.o
[ 17%] Building CXX object CMakeFiles/trantor.dir/trantor/net/Channel.cc.o
[ 18%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Acceptor.cc.o
[ 19%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Connector.cc.o
[ 20%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Poller.cc.o
[ 21%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Socket.cc.o
[ 22%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/TcpConnectionImpl.cc.o
[ 23%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Timer.cc.o
[ 25%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/TimerQueue.cc.o
[ 26%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/poller/EpollPoller.cc.o
[ 27%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/poller/KQueue.cc.o
[ 28%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/poller/PollPoller.cc.o
[ 29%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/tlsprovider/BotanTLSProvider.cc.o
/Users/runner/work/trantor/trantor/trantor/net/inner/tlsprovider/BotanTLSProvider.cc:345:10: error: 'BotanTLSProvider::tls_verify_cert_chain' hides overloaded virtual function [-Werror,-Woverloaded-virtual]
void tls_verify_cert_chain(
^
/usr/local/Cellar/botan/3.2.0/include/botan-3/botan/tls_callbacks.h:167:20: note: hidden overloaded virtual function 'Botan::TLS::Callbacks::tls_verify_cert_chain' declared here: type mismatch at 5th parameter ('std::string_view' (aka 'basic_string_view') vs 'const std::string &' (aka 'const basic_string<char, char_traits, allocator> &'))
virtual void tls_verify_cert_chain(const std::vector<X509_Certificate>& cert_chain,
^
1 error generated.
make[2]: *** [CMakeFiles/trantor.dir/trantor/net/inner/tlsprovider/BotanTLSProvider.cc.o] Error 1
make[1]: *** [CMakeFiles/trantor.dir/all] Error 2
make: *** [all] Error 2

Define Socket Options, instead of writing a method to each one

Description

Hi, would be nice as user point of view, to have the socket options already created, and also, let the user define if needed. So instead of him, know what is the option level, the option name, what is the value and so on ...
We could have something like:

static const Option<std::int32_t> TCP_CORKING;
static const Option<std::int32_t> REUSE_ADDRESS;

With this, we could create as many options are there, and, with the benefit of templates compile time code generation, we could write just one setsockopt ...

I was seeing Socket.h, and noticied:

///
/// Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
///
void setTcpNoDelay(bool on);

///
/// Enable/disable SO_REUSEADDR
///
void setReuseAddr(bool on);

///
/// Enable/disable SO_REUSEPORT
///
void setReusePort(bool on);

///
/// Enable/disable SO_KEEPALIVE
///
void setKeepAlive(bool on);

This works fine, but leads to duplicated code ...

Example

A more detailed example: Socket.h

class Socket
{
public:
    template <typename OPTION_TYPE>
    struct Option
    {
        Option(const std::int32_t level, const std::int32_t value)
            : level(level), value(value), size(sizeof(OPTION_TYPE))
        {
        }

        /**
            * The level argument
            */
        const std::int32_t level;

        /**
        * The optname argument
        )*/
        const std::int32_t value;

        /**
            * The optlen argument
            */
        const std::int32_t size;

        /**
            * read from socket buffer size
            */
        static const Option<std::int32_t> READ_BUFFER_SIZE_TYPE;

        /**
            * When reading from socket, we define the timeout
            */
        static const Option<struct timeval> READ_TIMEOUT;

        /**
            * Minimum number of bytes to consider the buffer as readable
            * Can be useful if want to use batch messages
            */
        static const Option<std::int32_t>
            MINIMUM_BYTES_TO_CONSIDER_BUFFER_AS_READABLE;

        /**
            * This option is used to enable the TCP Corking mechanism,
            * which delays sending small packets in order to optimize network
            * throughput.
            */
        static const Option<std::int32_t> TCP_CORKING;

        /**
            * Indicates that the rules used in validating addresses
            * supplied in a bind(2) call should allow reuse of local
            * addresses. For AF_INET sockets this means that a socket
            * may bind, except when there is an active listening socket
            * bound to the address. When the listening socket is bound
            * to INADDR_ANY with a specific port then it is not possible
            * to bind to this port for any local address.
            */
        static const Option<std::int32_t> REUSE_ADDRESS;

        /**
            * Permits multiple AF_INET or AF_INET6 sockets to be bound
            * to an identical socket address. This option must be set
            * on each socket (including the first socket) prior to
            * calling bind(2) on the socket. To prevent port hijacking,
            * all of the processes binding to the same address must have
            * the same effective UID. This option can be employed with
            * both TCP and UDP sockets.
            */
        static const Option<std::int32_t> REUSE_PORT;
        /*
            *  If set, disable the Nagle algorithm.  This means that
            *  segments are always sent as soon as possible, even if
            *  there is only a small amount of data.  When not set, data
            *  is buffered until there is a sufficient amount to send
            *  out, thereby avoiding the frequent sending of small
            *  packets, which results in poor utilization of the network.

            * https://en.wikipedia.org/wiki/Nagle%27s_algorithm its useful to
            undestand this ...
        */
        static const Option<std::int32_t> TCP_NO_DELAY;

            /**
            * If defined, tries to send al enqued messages before socket.close or
            * socket.shutdown return. So, if the send exceeds the timeout defined
            * in the linger option
            */
        static const Option<struct linger> LINGER;
    };

    template <typename VALUE_TYPE>
    struct OptionValue
    {
        OptionValue(const VALUE_TYPE value_type, const Option<VALUE_TYPE>& type) : value_type(value_type), type(type)
        {}

        /**
        * Since the options are static instances, we can use lvalue here
        */
        const Option<VALUE_TYPE>& type;

        const VALUE_TYPE value_type;
    };

    template <typename TYPE>
    void set_option(const OptionValue<TYPE> option) const
    {
        int32_t level = option.type.level;
        int32_t opt_name = option.type.value;
        TYPE t = option.value_type;
        void* opt_value = &(t);
        socklen_t opt_len = option.type.size;
        if (::setsockopt(file_descriptor, level, opt_name, opt_value, opt_len) == -1)
        {
            perror("setsockopt");
        }
    };

    template <typename TYPE>
    const OptionValue<TYPE> get_option(const Option<TYPE>& type) const
    {
        int32_t socketfd = file_descriptor;
        int32_t level = type.level;
        int32_t opt_name = type.value;

        /**
            * NOTE: This is not a Variable Length Array.
            * We can achive this, with templates, so its know at compile time how
            * big it is.
            */
        std::int8_t buffer[type.size];
        socklen_t opt_len;
        if (::getsockopt(socketfd, level, opt_name, buffer, &opt_len) == -1)
        {
            perror("getsockopt");
        }
        TYPE* t = reinterpret_cast<TYPE*>(buffer);
        const OptionValue<TYPE> result(*t, type);
        return result;
    }
}

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::TCP_CORKING;

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::MINIMUM_BYTES_TO_CONSIDER_BUFFER_AS_READABLE;

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::READ_BUFFER_SIZE_TYPE;

template <>
Socket::Option<struct timeval> const Socket::Option<struct timeval>::READ_TIMEOUT;

template <>
Socket::Option<std::int32_t> const Socket::Option<std::int32_t>::REUSE_ADDRESS;

template <>
Socket::Option<std::int32_t> const Socket::Option<std::int32_t>::REUSE_PORT;

template <>
Socket::Option<std::int32_t> const Socket::Option<std::int32_t>::TCP_NO_DELAY;

template <>
Socket::Option<struct linger> const Socket::Option<struct linger>::LINGER;

And, Socket.cc

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::READ_BUFFER_SIZE_TYPE(SOL_SOCKET, SO_RCVBUF);

template <>
Socket::Option<struct timeval> const Socket::Option<struct timeval>::READ_TIMEOUT(SOL_SOCKET, SO_RCVTIMEO);

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::MINIMUM_BYTES_TO_CONSIDER_BUFFER_AS_READABLE(SOL_SOCKET, SO_RCVLOWAT);

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::TCP_CORKING(IPPROTO_TCP, TCP_CORK);

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::REUSE_ADDRESS(SOL_SOCKET, SO_REUSEADDR);

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::REUSE_PORT(SOL_SOCKET,SO_REUSEPORT);

template <>
Socket::Option<int32_t> const Socket::Option<int32_t>::TCP_NO_DELAY(IPPROTO_TCP, TCP_NODELAY);

template <>
Socket::Option<struct linger> const Socket::Option<struct linger>::LINGER(SOL_SOCKET, SO_LINGER);

Note: The code of set_option and get_option must be in the header file, because we are using templates.
Note sure if there is a more elegant way ...

And, the usage:

void on_connection(const Socket& client)
{
    // Enable TCP CORK
    client.set_option(Socket::OptionValue<int32_t>(1, Socket::Option<int32_t>::TCP_CORKING));

    // Check if CORK is enabled
    cout << "CORK enabled? " << (client.get_option(Socket::Option<int32_t>::TCP_CORKING).value_type ? "true" : "false");
}

If you liked, and accept. I would like to implement it!

Thanks!

Issues compiling on Alpine Linux

I had to make a couple of modifications to InetAddress.cc to get trantor to compile on Alpine. Not sure if they are good, since the drogon test suite crashes, but still you may want to take a look at the patch.

`diff --git a/trantor/net/InetAddress.cc b/trantor/net/InetAddress.cc
index db6339d..bf306a3 100755
--- a/trantor/net/InetAddress.cc
+++ b/trantor/net/InetAddress.cc
@@ -46,9 +46,9 @@ static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK;
using namespace trantor;

#ifdef linux
-#if !(__GNUC_PREREQ(4, 6))
-#pragma GCC diagnostic ignored "-Winvalid-offsetof"
-#endif
+//#if !(__GNUC_PREREQ(4, 6))
+//#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+//#endif
#endif
InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6)
: _isIpV6(ipv6)
@@ -192,7 +192,7 @@ const uint32_t *InetAddress::ip6NetEndian() const
{
//assert(family() == AF_INET6);
#ifdef linux

  • return _addr6.sin6_addr.__in6_u.__u6_addr32;
  • return _addr6.sin6_addr.__in6_union.__s6_addr32;
    #else
    return _addr6.sin6_addr.__u6_addr.__u6_addr32;
    #endif`

assertInLoopThread fails in AresResolver during EventLoopThread destruction

During the destruction of EventLoopThread objects, there is a socket change that gets picked up by AresResolver that fails the assertInLoopThread assertion. Based on my limited understanding of what's happening, I think it should first check if loopValid_ is true before trying to do this. Maybe these lines should be moved into the else if block when loopValid_ is true?

Thread 1 "python3" hit Breakpoint 1, trantor::EventLoop::abortNotInLoopThread (this=0x7fc1f9e05010) at /tmp/drogon/trantor/trantor/net/EventLoop.cc:266
266         LOG_FATAL << "It is forbidden to run loop on threads other than event-loop "
(gdb) where
#0  trantor::EventLoop::abortNotInLoopThread (this=0x7fc1f9e05010) at /tmp/drogon/trantor/trantor/net/EventLoop.cc:266
#1  0x00007fc208850fb5 in trantor::EventLoop::assertInLoopThread (this=0x7fc1f9e05010) at /tmp/drogon/trantor/trantor/net/EventLoop.h:82
#2  0x00007fc20821005e in trantor::AresResolver::onSockStateChange (this=0x7fc1f9e050b0, sockfd=24, read=false, write=false) at /tmp/drogon/trantor/trantor/net/inner/AresResolver.cc:205
#3  0x00007fc2082104a3 in trantor::AresResolver::ares_sock_statecallback_ (data=0x7fc1f9e050b0, sockfd=24, read=0, write=0) at /tmp/drogon/trantor/trantor/net/inner/AresResolver.cc:258
#4  0x00007fc202350097 in ares.close_sockets () from /usr/local/lib/libcares.so.2
#5  0x00007fc2023515d5 in ares.destroy_servers_state () from /usr/local/lib/libcares.so.2
#6  0x00007fc2023514b9 in ares_destroy () from /usr/local/lib/libcares.so.2
#7  0x00007fc20820f6e7 in trantor::AresResolver::~AresResolver (this=0x7fc1f9e050b0, __in_chrg=<optimized out>) at /tmp/drogon/trantor/trantor/net/inner/AresResolver.cc:109
...
#23 0x00007fc208201ece in trantor::Timer::~Timer (this=0x7fc1f9e001a0, __in_chrg=<optimized out>) at /tmp/drogon/trantor/trantor/net/inner/Timer.h:39
...
#37 0x00007fc2082000f0 in trantor::TimerQueue::~TimerQueue (this=0x7fc1f9e11000, __in_chrg=<optimized out>) at /tmp/drogon/trantor/trantor/net/inner/TimerQueue.cc:173
...
#40 0x00007fc2081bccc2 in trantor::EventLoop::~EventLoop (this=0x7fc1f9e05010, __in_chrg=<optimized out>) at /tmp/drogon/trantor/trantor/net/EventLoop.cc:114
...
#48 0x00007fc2081c04cd in trantor::EventLoopThread::~EventLoopThread (this=0x7fc20f1e3b80, __in_chrg=<optimized out>) at /tmp/drogon/trantor/trantor/net/EventLoopThread.cc:34

trantor/utils/Utilities.cc:22:10: fatal error: xlocale.h: No such file or directory

Error:

ERROR: /home/username/.cache/bazel/_bazel_username/73dfd4fd85663bb6f1bb50c53ee60ba3/external/trantor/BUILD.bazel:109:11: Compiling trantor/utils/Utilities.cc failed: (Exit 1): gcc failed: error executing command
  (cd /home/username/.cache/bazel/_bazel_username/73dfd4fd85663bb6f1bb50c53ee60ba3/execroot/foo && \
...
    PWD=/proc/self/cwd \
  /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x' -MD -MF bazel-out/k8-fastbuild/bin/external/trantor/_objs/trantor/Utilities.pic.d '-frandom-seed=bazel-out/k8-fastbuild/bin/external/trantor/_objs/trantor/Utilities.pic.o' -fPIC -iquote external/trantor -iquote bazel-out/k8-fastbuild/bin/external/trantor -iquote external/boringssl -iquote bazel-out/k8-fastbuild/bin/external/boringssl -Ibazel-out/k8-fastbuild/bin/external/trantor/_virtual_includes/trantor -isystem external/trantor/trantor -isystem bazel-out/k8-fastbuild/bin/external/trantor/trantor -isystem external/trantor/trantor/utils -isystem bazel-out/k8-fastbuild/bin/external/trantor/trantor/utils -isystem external/trantor/trantor/net -isystem bazel-out/k8-fastbuild/bin/external/trantor/trantor/net -isystem external/trantor/trantor/net/inner -isystem bazel-out/k8-fastbuild/bin/external/trantor/trantor/net/inner -isystem external/boringssl/src/include -isystem bazel-out/k8-fastbuild/bin/external/boringssl/src/include -isystem bazel-out/k8-fastbuild/bin/external/cares/libcares/include -DHAVE_BAZEL_BUILD '-std=c++2a' -Wall -Wreturn-type -Wuninitialized -Wunused-result '-Werror=narrowing' '-Werror=reorder' -Wunused-local-typedefs '-Werror=conversion-null' '-Werror=overlength-strings' '-Werror=pointer-arith' '-Werror=varargs' '-Werror=vla' '-Werror=write-strings' -Wmissing-declarations '-fdiagnostics-color=always' '-std=c++17' -Wconversion -fno-canonical-system-headers -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c external/trantor/trantor/utils/Utilities.cc -o bazel-out/k8-fastbuild/bin/external/trantor/_objs/trantor/Utilities.pic.o)
Execution platform: @local_config_platform//:host
external/trantor/trantor/utils/Utilities.cc:22:10: fatal error: xlocale.h: No such file or directory
   22 | #include <xlocale.h>
      |          ^~~~~~~~~~~
compilation terminated.
INFO: Elapsed time: 3.431s, Critical Path: 0.12s
INFO: 17 processes: 17 internal.
FAILED: Build did NOT complete successfully

OS and compiler information:

❯ uname -a
Linux mustang 5.10.43.3-microsoft-standard-WSL2 #1 SMP Wed Jun 16 23:47:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
❯ gcc --version
gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Probable cause:

I believe the header has been removed.
https://sourceware.org/glibc/wiki/Release/2.26#Removal_of_.27xlocale.h.27

Document and Example

What's you idea about writing some information about library for example :

  • Feature highlights
  • documents
  • Supported OSs
  • Description
  • Simple Example

Crash when exiting program, after exiting event loop via exception

When a controller constructor throws, the event loop appears to exit cleanly after merging PR #224 . However, when the program exits, a fatal error is triggered. Minimal reproduction using Drogon:

Create a Drogon project with a controller:

drogon_ctl create project CrashExample
cd CrashExample/controllers
drogon_ctl create controller ExceptionalController

Edit main.cc and controllers/ExceptionalController.h to read:

// ExceptionalController.h
#pragma once

#include <drogon/HttpSimpleController.h>

using namespace drogon;

class ExceptionalController : public drogon::HttpSimpleController<ExceptionalController>
{
  public:
    ExceptionalController() {
      throw std::runtime_error("I'm exceptional, and therefore won't start. That should be fine.");
    }

    void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;
    PATH_LIST_BEGIN
    // list path definitions here;
    //PATH_ADD("/path", "filter1", "filter2", HttpMethod1, HttpMethod2...);

    PATH_ADD("/crash", Get);
    PATH_LIST_END
};
//main.cc

#include <drogon/drogon.h>
int main() {
    //Set HTTP listener address and port
    drogon::app().addListener("0.0.0.0",80);
    //Load config file
    //drogon::app().loadConfigFile("../config.json");
    //Run HTTP framework,the method will block in the internal event loop
    try {
        drogon::app().run();
    } catch (std::exception & e) {
        std::cout << "Caught exception \"" << e.what() << "\"... this is exiting.\n";
    }

    std::cout << "Press enter to exit...\n";
    std::getchar();

    return 0;
}

Build and run the app, press enter when prompted. Expected output:

20220926 06:35:01.622763 UTC 41933 WARN  Exception thrown from event loop, rethrowing after running functions on quit - EventLoop.cc:243
20220926 06:35:01.623295 UTC 41933 WARN  Rethrowing exception from event loop - EventLoop.cc:260
Caught exception "I'm exceptional, and therefore won't start. That should be fine."... this is exiting.
Press enter to exit...

Actual output:

20220926 06:35:01.622763 UTC 41933 WARN  Exception thrown from event loop, rethrowing after running functions on quit - EventLoop.cc:243
20220926 06:35:01.623295 UTC 41933 WARN  Rethrowing exception from event loop - EventLoop.cc:260
Caught exception "I'm exceptional, and therefore won't start. That should be fine."... this is exiting.
Press enter to exit...

20220926 06:35:05.766527 UTC 41933 FATAL It is forbidden to run loop on threads other than event-loop thread - EventLoop.cc:266

In other words, the event loop is still left in some illegal state. Note that the fatal error only appears after pressing enter.

Build Error

Envirmorment

Centos7
cmake version 3.27.3
gcc version 13.2.0 (GCC)

I want to build drogon in linux_x86-64
I have execute cmake .. ,

-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- compiler: GNU
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Looking for C++ include any
-- Looking for C++ include any - found
-- Looking for C++ include string_view
-- Looking for C++ include string_view - found
-- Looking for C++ include coroutine
-- Looking for C++ include coroutine - not found
-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR) 
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.27.1") 
-- Could NOT find Botan (missing: Botan_LIBRARIES Botan_INCLUDE_DIRS) 
-- Trantor using SSL library: None
-- Could NOT find c-ares (missing: C-ARES_INCLUDE_DIRS C-ARES_LIBRARIES) 
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Looking for C++ include filesystem
-- Looking for C++ include filesystem - found
-- Performing Test CXX_FILESYSTEM_NO_LINK_NEEDED
-- Performing Test CXX_FILESYSTEM_NO_LINK_NEEDED - Success
-- Found std::filesystem
-- use c++17
-- Found Jsoncpp: /usr/local/include  
-- jsoncpp verson:1.9.5
-- yaml-cpp not used
-- Found UUID: /lib64/libuuid.so
-- Could NOT find BROTLI (missing: BROTLIDEC_LIBRARY BROTLIENC_LIBRARY BROTLICOMMON_LIBRARY BROTLI_INCLUDE_DIR) 
-- Could NOT find PostgreSQL (missing: PostgreSQL_LIBRARY PostgreSQL_INCLUDE_DIR) 
-- Could NOT find pg (missing: PG_LIBRARIES PG_INCLUDE_DIRS) 
-- MySql was not found.
-- sqlite3 was not found.
-- Could NOT find Hiredis (missing: HIREDIS_LIBRARY HIREDIS_INCLUDE_DIR) 
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.7")  
-- cspFile:/home/drogon/drogon_ctl/templates/cmake.csp
-- view classname:cmake
-- cspFile:/home/drogon/drogon_ctl/templates/config_json.csp
-- view classname:config_json
-- cspFile:/home/drogon/drogon_ctl/templates/config_yaml.csp
-- view classname:config_yaml
-- cspFile:/home/drogon/drogon_ctl/templates/demoMain.csp
-- view classname:demoMain
-- cspFile:/home/drogon/drogon_ctl/templates/filter_cc.csp
-- view classname:filter_cc
-- cspFile:/home/drogon/drogon_ctl/templates/filter_h.csp
-- view classname:filter_h
-- cspFile:/home/drogon/drogon_ctl/templates/gitignore.csp
-- view classname:gitignore
-- cspFile:/home/drogon/drogon_ctl/templates/model_cc.csp
-- view classname:model_cc
-- cspFile:/home/drogon/drogon_ctl/templates/model_h.csp
-- view classname:model_h
-- cspFile:/home/drogon/drogon_ctl/templates/model_json.csp
-- view classname:model_json
-- cspFile:/home/drogon/drogon_ctl/templates/plugin_cc.csp
-- view classname:plugin_cc
-- cspFile:/home/drogon/drogon_ctl/templates/plugin_h.csp
-- view classname:plugin_h
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_base_cc.csp
-- view classname:restful_controller_base_cc
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_base_h.csp
-- view classname:restful_controller_base_h
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_cc.csp
-- view classname:restful_controller_cc
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_custom_cc.csp
-- view classname:restful_controller_custom_cc
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_custom_h.csp
-- view classname:restful_controller_custom_h
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_h.csp
-- view classname:restful_controller_h
-- cspFile:/home/drogon/drogon_ctl/templates/test_cmake.csp
-- view classname:test_cmake
-- cspFile:/home/drogon/drogon_ctl/templates/test_main.csp
-- view classname:test_main
-- bin:bin
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Configuring done (5.4s)
-- Generating done (0.1s)
-- Build files have been written to: /home/drogon/build

and then when I execute make, it occur:

image

it seems like that the compile don‘t support unique_ptr?

FATAL no writing but write callback called - TcpConnectionImpl.cc:328

I’m using Drogon’s HttpClient but figured it would make more sense to put this here:

  • Using v1.9.1 of Drogon and v1.5.15 of Trantor.
  • It’s in an AWS environment that I can’t easily modify or put more verbose logging on. I’ve been unsuccessful in getting any kind of repro in a simpler environment.
  • Not sure how to quantify it but I guess pretty infrequent. This env has ~50 TCP connections (as far as HttpClient is concerned) and this gets logged once every ~5,000,000 requests.
  • Load on the server - and the client in particular - doesn’t seem to matter. It seems to happen specifically when the network is unstable.
    • If a sendRequest() fails with “Timeout” status then there’s no log.
    • If a sendRequest() fails with “Network failure” status then this log sometimes accompanies it.

I realize it’s a high ask to fix this under these conditions. I’m more curious if it’s safe to ignore this and if we can downgrade the log severity. I haven’t noticed any kind of memory corruption (though haven't actually had it happen under ASan) or resource exhaustion accompanying it.

(I also noticed this change from a couple hours ago. If that’s likely relevant I’m happy to upgrade and report back when it’s released.)

Cannot send email using SMTPMail plugin

Trantor gives following errors:

20210913 13:58:12.810493 UTC 57380 ERROR Domain validation failed - TcpConnectionImpl.cc:1677
20210913 13:58:12.810536 UTC 57380 ERROR SSL certificate validation failed. - TcpConnectionImpl.cc:1696

I am using letsencrypt certificates and can send email using mail command.

TcpConnectionImpl.cc logs the connections aborted by a client as an unexpected error

TcpConnectionImpl.cc line 482

               if (errno == EPIPE || errno == ECONNRESET)  // TODO: any others?
                {
#ifdef _WIN32
                    LOG_TRACE << "WSAENOTCONN or WSAECONNRESET, errno="
                              << errno;
#else
                    LOG_TRACE << "EPIPE or ECONNRESET, errno=" << errno;
#endif
                    return;
                }
                LOG_SYSERR << "Unexpected error(" << errno << ")";
                return;

If client aborted connection (it has a right to do it in any moment, and it is not error in program logic (though error of write function), it should not be logged as unexpected error to attract attention. It should be or silenced, or reported as "Client aborted connection"
Otherwise, it look like error in the program code.

errno == 10053 , WSAECONNABORTED in Windows.

Build error

Call to 'newTLSProvider' is ambiguous
seems that the return type is difference

image image

consider adding TCP_KEEPCNT, TCP_KEEPIDLE,TCP_KEEPINTVL settings from environment variable?

Sometimes we need to set these three values, But we are unable to modify the system configuration, Currently, the trantor does not provide an interface to set it up

if(const char* env_p = std::getenv("TRANTOR_TCP_KEEPCNT")) {
    int optval = std::atoi(env_p)
    setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &optval, optlen);
    // setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen);
    // setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen);
}

MessageCallback is not work while TcpClient continue sending tcp message

client's ConnectionCallback like this:

        client[i]->setSockOptCallback([](int fd) {
            int optval = 10;
            ::setsockopt(fd,
                         SOL_TCP,
                         TCP_KEEPCNT,
                         &optval,
                         static_cast<socklen_t>(sizeof optval));
            ::setsockopt(fd,
                         SOL_TCP,
                         TCP_KEEPIDLE,
                         &optval,
                         static_cast<socklen_t>(sizeof optval));
            ::setsockopt(fd,
                         SOL_TCP,
                         TCP_KEEPINTVL,
                         &optval,
                         static_cast<socklen_t>(sizeof optval));
        });

        client[i]->setConnectionCallback(
            [i, &connCount, &str_msg](const TcpConnectionPtr &conn) {
                if (conn->connected())
                {
                    LOG_DEBUG << i << " connected!";
                    while (isContinue) {
                        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                        conn->send(str_msg + '|');
                    }   
                }
                else
                {
                    LOG_DEBUG << i << " disconnected";
                    --connCount;
                    if (connCount == 0)
                        loop.quit();
                }
            });

        client[i]->setMessageCallback(
            [i, &connCount, &reader](const TcpConnectionPtr &conn, MsgBuffer *buf) {
                size_t byte_len = buf->readableBytes();
                LOG_INFO << "recv " << byte_len << " bytes msg";

                std::vector<std::string> msg_array;
                splitString(buf->read(byte_len), '|', msg_array);

                for (std::string str_msg: msg_array){
                    Json::Value msg;
                    if (!reader.parse(str_msg, msg) || !msg.isObject() || !msg.isMember("code") || msg["code"].asInt() == 1) {
                        // 解析失败
                        LOG_DEBUG << "parse response error!";
                    }
                    else {
                        LOG_INFO << "parse response success!";
                        unTotalTimes++;
                    }
                }
            });

when i run TcpServer and TcpClient,My MessageCallback does't work correctly. Here is the Packet capture。upper side is the TcpServer Console Log。downside is tcpdump info。localhost:53120 is client’s ip and port

tcpdump

TcpClient's Log is Here, which does't Log recv msg.

client

udp support

is there plan to support udp, or popular protocal building upon of udp such as quic?
thanks

LOG_DEBUG打印时间错误

我是win11操作系统,系统右下角显示的时间是2022年11月20号15:45分,但是log文件中显示的时间是:
20221120 07:45:07.178000 UTC 40984 DEBUG [preRegister]

Android compatibility

Just a single unused function in trantor/utils/LogStream.h, at line # 83, prevents a build in an Android app project:

    void bzero()
    {
        memset(data_, 0, sizeof(data_));
    }

If that could be changed to "buffzero" or something like that, not only trantor, but drogon is able to be included in any Android app.

Thanks!

off_t type error on windows

TcpConnectionImpl::sendFile

node->offset_ = static_cast<off_t>(offset);

TcpConnectionImpl::sendFileInLoop

filePtr->offset_ += static_cast<off_t>(nSend);

on windows,off_t is defined with long, not longlong,so big file(more than 4G) will be error offset......

drogon和这个项目能不能建个微信/QQ群?

个人很欣赏作者对muduo的改造,粗略看一下,去掉gcc的方言,去掉boost的各种依赖,重新引入C++17/14的promise的,重写TimerWheel,引入lambda,支持ssl,支持kqueue……,能不能建个微信/QQ群

Some filenames are in the wrong case, preventing Linux->Windows cross-compilation

Windows is not case-sensitive, so spelling includes and libraries in the wrong case doesn't do anything. But it's problematic when one tries to cross-compile from Linux.

I had to fix following includes:

  • #include <Windows.h> -> #include <windows.h>
  • #include <WinSock2.h> -> #include <winsock2.h>
    And library names for CMake:
  • Rpcrt4 -> rpcrt4
  • Crypt32 -> crypt32
  • Secur32 -> secur32

Error on compiling OpenSSLProvider.cc

Hi, I get the following error at compile time in the new version.

Host information:
OpenSSL version: 3.1.0
OS version: macOS 13.2.1
Arch: M1 Arm64

-- The C compiler identification is AppleClang 14.0.3.14030022
-- The CXX compiler identification is AppleClang 14.0.3.14030022
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Found OpenSSL: /opt/homebrew/Cellar/openssl@3/3.1.0/lib/libcrypto.dylib (found version "3.1.0")
-- Trantor using SSL library: OpenSSL
-- Found c-ares: /opt/homebrew/include
-- c-ares found!
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Found Doxygen: /opt/homebrew/bin/doxygen (found version "1.9.6") found components: doxygen dot missing components: dia
-- Configuring done (1.1s)
-- Generating done (0.0s)

build % make
[ 3%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/AsyncFileLogger.cc.o
[ 6%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/ConcurrentTaskQueue.cc.o
[ 10%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Date.cc.o
[ 13%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/LogStream.cc.o
[ 16%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Logger.cc.o
[ 20%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/MsgBuffer.cc.o
[ 23%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/SerialTaskQueue.cc.o
[ 26%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/TimingWheel.cc.o
[ 30%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Utilities.cc.o
[ 33%] Building CXX object CMakeFiles/trantor.dir/trantor/net/EventLoop.cc.o
[ 36%] Building CXX object CMakeFiles/trantor.dir/trantor/net/EventLoopThread.cc.o
[ 40%] Building CXX object CMakeFiles/trantor.dir/trantor/net/EventLoopThreadPool.cc.o
[ 43%] Building CXX object CMakeFiles/trantor.dir/trantor/net/InetAddress.cc.o
[ 46%] Building CXX object CMakeFiles/trantor.dir/trantor/net/TcpClient.cc.o
[ 50%] Building CXX object CMakeFiles/trantor.dir/trantor/net/TcpServer.cc.o
[ 53%] Building CXX object CMakeFiles/trantor.dir/trantor/net/Channel.cc.o
[ 56%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Acceptor.cc.o
[ 60%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Connector.cc.o
[ 63%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Poller.cc.o
[ 66%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Socket.cc.o
[ 70%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/TcpConnectionImpl.cc.o
[ 73%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/Timer.cc.o
[ 76%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/TimerQueue.cc.o
[ 80%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/poller/EpollPoller.cc.o
[ 83%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/poller/KQueue.cc.o
[ 86%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/poller/PollPoller.cc.o
[ 90%] Building CXX object CMakeFiles/trantor.dir/trantor/net/inner/tlsprovider/OpenSSLProvider.cc.o
/Users/user/drogon/trantor/trantor/net/inner/tlsprovider/OpenSSLProvider.cc:522:18: error: 'recvData' overrides a member function but is not marked 'override' [-Werror,-Winconsistent-missing-override]
virtual void recvData(MsgBuffer buffer)
^
/Users/user/drogon/trantor/trantor/net/inner/TLSProvider.h:35:18: note: overridden virtual function is here
virtual void recvData(MsgBuffer
buffer) = 0;
^
/Users/user/drogon/trantor/trantor/net/inner/tlsprovider/OpenSSLProvider.cc:562:21: error: 'sendData' overrides a member function but is not marked 'override' [-Werror,-Winconsistent-missing-override]
virtual ssize_t sendData(const char data, size_t len)
^
/Users/user/drogon/trantor/trantor/net/inner/TLSProvider.h:40:21: note: overridden virtual function is here
virtual ssize_t sendData(const char
ptr, size_t size) = 0;
^
2 errors generated.
make[2]: *** [CMakeFiles/trantor.dir/trantor/net/inner/tlsprovider/OpenSSLProvider.cc.o] Error 1
make[1]: *** [CMakeFiles/trantor.dir/all] Error 2
make: *** [all] Error 2

Build error with Clang 16

% ./build.sh
Deleted folder: ./build
Created building folder: ./build
Entering folder: ./build
Start building trantor ...
-- The C compiler identification is Clang 16.0.6
-- The CXX compiler identification is Clang 16.0.6
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/libexec/ccache/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/libexec/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) in CMakeLists.txt:
  A logical block opening on the line

    /home/vedranmiletic/workspace/drogon/trantor/CMakeLists.txt:53 (if)

  closes on the line

    /home/vedranmiletic/workspace/drogon/trantor/CMakeLists.txt:55 (endif)

  with mis-matching arguments.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Found OpenSSL: /usr/lib/libcrypto.so (found version "3.0.10")  
-- Trantor using SSL library: OpenSSL
-- Found c-ares: /usr/local/include  
-- c-ares found!
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Found Doxygen: /usr/local/bin/doxygen (found version "1.9.6") found components: doxygen dot missing components: dia
-- Configuring done (1.8s)
-- Generating done (0.0s)
-- Build files have been written to: /home/vedranmiletic/workspace/drogon/trantor/build
[  3%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/AsyncFileLogger.cc.o
[  6%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/ConcurrentTaskQueue.cc.o
[ 10%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Date.cc.o
[ 13%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/LogStream.cc.o
[ 16%] Building CXX object CMakeFiles/trantor.dir/trantor/utils/Logger.cc.o
/home/vedranmiletic/workspace/drogon/trantor/trantor/utils/Logger.cc:396:5: error: expression result unused [-Werror,-Wunused-value]
    (bool)logger;
    ^     ~~~~~~
1 error generated.
*** Error code 1

Stop.
make[2]: stopped in /home/vedranmiletic/workspace/drogon/trantor/build
*** Error code 1

Stop.
make[1]: stopped in /home/vedranmiletic/workspace/drogon/trantor/build
*** Error code 1

Stop.
make: stopped in /home/vedranmiletic/workspace/drogon/trantor/build

This is on FreeBSD, which might or might not be relevant.

Build Error

Envirmorment

Centos7
cmake version 3.27.3
gcc version 13.2.0 (GCC)

I have execute cmake .. ,

-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- compiler: GNU
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Looking for C++ include any
-- Looking for C++ include any - found
-- Looking for C++ include string_view
-- Looking for C++ include string_view - found
-- Looking for C++ include coroutine
-- Looking for C++ include coroutine - not found
-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR) 
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.27.1") 
-- Could NOT find Botan (missing: Botan_LIBRARIES Botan_INCLUDE_DIRS) 
-- Trantor using SSL library: None
-- Could NOT find c-ares (missing: C-ARES_INCLUDE_DIRS C-ARES_LIBRARIES) 
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Looking for C++ include filesystem
-- Looking for C++ include filesystem - found
-- Performing Test CXX_FILESYSTEM_NO_LINK_NEEDED
-- Performing Test CXX_FILESYSTEM_NO_LINK_NEEDED - Success
-- Found std::filesystem
-- use c++17
-- Found Jsoncpp: /usr/local/include  
-- jsoncpp verson:1.9.5
-- yaml-cpp not used
-- Found UUID: /lib64/libuuid.so
-- Could NOT find BROTLI (missing: BROTLIDEC_LIBRARY BROTLIENC_LIBRARY BROTLICOMMON_LIBRARY BROTLI_INCLUDE_DIR) 
-- Could NOT find PostgreSQL (missing: PostgreSQL_LIBRARY PostgreSQL_INCLUDE_DIR) 
-- Could NOT find pg (missing: PG_LIBRARIES PG_INCLUDE_DIRS) 
-- MySql was not found.
-- sqlite3 was not found.
-- Could NOT find Hiredis (missing: HIREDIS_LIBRARY HIREDIS_INCLUDE_DIR) 
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.7")  
-- cspFile:/home/drogon/drogon_ctl/templates/cmake.csp
-- view classname:cmake
-- cspFile:/home/drogon/drogon_ctl/templates/config_json.csp
-- view classname:config_json
-- cspFile:/home/drogon/drogon_ctl/templates/config_yaml.csp
-- view classname:config_yaml
-- cspFile:/home/drogon/drogon_ctl/templates/demoMain.csp
-- view classname:demoMain
-- cspFile:/home/drogon/drogon_ctl/templates/filter_cc.csp
-- view classname:filter_cc
-- cspFile:/home/drogon/drogon_ctl/templates/filter_h.csp
-- view classname:filter_h
-- cspFile:/home/drogon/drogon_ctl/templates/gitignore.csp
-- view classname:gitignore
-- cspFile:/home/drogon/drogon_ctl/templates/model_cc.csp
-- view classname:model_cc
-- cspFile:/home/drogon/drogon_ctl/templates/model_h.csp
-- view classname:model_h
-- cspFile:/home/drogon/drogon_ctl/templates/model_json.csp
-- view classname:model_json
-- cspFile:/home/drogon/drogon_ctl/templates/plugin_cc.csp
-- view classname:plugin_cc
-- cspFile:/home/drogon/drogon_ctl/templates/plugin_h.csp
-- view classname:plugin_h
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_base_cc.csp
-- view classname:restful_controller_base_cc
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_base_h.csp
-- view classname:restful_controller_base_h
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_cc.csp
-- view classname:restful_controller_cc
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_custom_cc.csp
-- view classname:restful_controller_custom_cc
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_custom_h.csp
-- view classname:restful_controller_custom_h
-- cspFile:/home/drogon/drogon_ctl/templates/restful_controller_h.csp
-- view classname:restful_controller_h
-- cspFile:/home/drogon/drogon_ctl/templates/test_cmake.csp
-- view classname:test_cmake
-- cspFile:/home/drogon/drogon_ctl/templates/test_main.csp
-- view classname:test_main
-- bin:bin
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Configuring done (5.4s)
-- Generating done (0.1s)
-- Build files have been written to: /home/drogon/build

and then when I execute make, it occur:

image

it seems like that the compile don‘t support unique_ptr?

`trantor::ConcurrentTaskQueue::runTaskInQueue` hangs indefinitely

On a hosted server with SSL certificates, all functions and API endpoints that relied on trantor::ConcurrentTaskQueue::runTaskInQueue started hanging indefinitely as if the mutex is locked and never unlocked, or something is blocking the queue. runTaskInQueue itself doesn't hang, print statements after it get printed as expected, so it is not an issue of the mutex, it is the task just never executing.

I checked with trantor::ConcurrentTaskQueue::getTaskCount(), and it reported 0 just before the call to runTaskInQueue.

Had to strip all logic that relied on it for the sake of allowing it to work.

Logs were on debug, and may not be of much use.

20240226 14:47:23.450161 UTC 453455 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 15:09:03.516471 UTC 453457 FATAL Transport endpoint is not connected (errno=107) sockets::shutdownWrite - Socket.cc:110
20240226 15:36:22.890503 UTC 453458 FATAL Transport endpoint is not connected (errno=107) sockets::shutdownWrite - Socket.cc:110
20240226 17:40:28.126379 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:40:31.175445 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:40:41.949825 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:40:58.126485 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:01.175529 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:11.949927 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:13.960462 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:28.126542 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:31.175616 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:41.949993 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:43.960552 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:41:58.126624 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:01.175703 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:11.950088 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:13.960643 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:28.126716 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:31.175792 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:41.950183 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:43.960743 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:42:58.126812 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:01.175919 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:11.950284 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:13.960845 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:26.760234 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:28.126923 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:29.283758 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:31.176001 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:41.950373 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:43.960968 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:56.760326 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:58.127024 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:43:59.283924 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:01.176101 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:11.950487 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:13.961030 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:26.760437 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:28.127109 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:29.284003 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:31.176211 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:41.950573 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:43.961129 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:56.760518 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:58.127206 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:44:59.284053 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:01.176295 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:11.950680 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:13.961233 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:26.760619 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:28.127291 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:29.284147 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:31.176335 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:41.950777 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:43.961355 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:56.760718 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:58.127397 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:45:59.284239 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:01.176425 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:11.950871 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:13.961458 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:26.760789 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:28.127483 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:29.284349 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:31.176532 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:41.950975 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:43.961570 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:56.760900 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:58.127574 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:46:59.284457 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:01.176632 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:11.951066 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:13.961679 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:26.760994 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:28.127679 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:29.284545 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:31.176727 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:41.951143 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:43.961769 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:56.761100 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:58.127788 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:47:59.284652 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:01.176848 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:11.951228 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:13.961884 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:26.761188 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:28.127899 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:29.284742 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:31.176933 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:41.951318 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:43.961970 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:56.761327 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:58.127984 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:48:59.284841 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:01.177047 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:11.951407 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:13.962065 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:26.761436 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:28.128060 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:29.284929 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:31.177106 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:41.951502 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:43.962153 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:56.761538 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:58.128170 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:49:59.284980 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:01.177197 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:11.951614 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:13.962248 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:26.761621 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:28.128257 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:29.285074 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:31.177287 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:41.951701 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:43.962348 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:56.761741 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:58.128344 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:50:59.285161 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:51:01.177489 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:51:11.951828 UTC 453457 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:51:13.962451 UTC 453458 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:51:26.761842 UTC 453459 WARN  Connection is not connected,give up sending - TcpConnectionImpl.cc:390
20240226 17:51:36.907095 UTC 457571 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 17:53:16.746372 UTC 457809 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 17:58:47.184918 UTC 458159 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:00:22.936246 UTC 458448 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:02:33.937763 UTC 458734 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:03:48.502096 UTC 459007 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:07:38.125654 UTC 1276 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:14:08.138407 UTC 2319 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:17:31.759736 UTC 2632 INFO  Start child process - HttpAppFrameworkImpl.cc:580
20240226 18:18:04.478187 UTC 2632 WARN  SIGINT signal received. - HttpAppFrameworkImpl.cc:177
20240226 18:19:32.625443 UTC 2632 WARN  SIGTERM signal received. - HttpAppFrameworkImpl.cc:172

Additional context
The server was working fine for the past few days, but an hour ago it started not responding to any API endpoints.
Restarting the host did not help either.
And it serves files just fine.

Things that were changed which could have potentially led to this:

  1. Set relaunchOnError to true
  2. Enabled file based logging

How To Exit TcpServer in trantor/trantor/test/KickoffTest.cc ?

In KickoffTest.cc, a Tcpserver Object is created. I wanted to exit this server when there is no client connection. The following is my code:

int main()
{
    /**** omit for same code ********/
    ....
    server.setConnectionCallback([&n](const TcpConnectionPtr &connPtr) {
        if (connPtr->connected())
        {
            ++n;
            if (n % 2 == 0)
            {
                connPtr->keepAlive();
            }
            LOG_DEBUG << "New connection";
        }
        else if (connPtr->disconnected())
        {
            LOG_DEBUG << "connection disconnected";
            /*** Begin: My Added Code****/
            --n;
            if(n == 0) 
            {
               loop.runInLoop([&server]() {
                 server.stop();
               });
            }
            /*** End: My Added Code****/
        }
    });
    server.setIoLoopNum(3);
    server.start();
    loop.loop();
}

My Added Code marked the codes that i added. And the server got stucked in line server.stop();.

How to solve it and how to exit a tcp server gracefully?

[sugestion] runAfter, runEvery etc. could be overloaded to use chrono literals

I see in trantor there are lots of methods that take time duration as a parameters. A possible enhancement could be using chrono literals to write 1s, 10min. Example methods were such overloads would be useful are:

TimerId runAfter(double delay, const Func &cb);
TimerId runAfter(double delay, Func &&cb);
///
/// Runs callback every @c interval seconds.
/// Safe to call from other threads.
///
TimerId runEvery(double interval, const Func &cb);
TimerId runEvery(double interval, Func &&cb);

Assertion `ssl_' failed

A Drogon webserver with WebSockets has been crashing randomly from time to time, the TRACE logs contain the following:

20240229 09:02:23.470644 UTC 24915 TRACE [onHttpRequest] new request:<Hidden>:63375->10.19.0.5:443 - HttpServer.cc:345
20240229 09:02:23.470652 UTC 24915 TRACE [onHttpRequest] Headers POST /api/data/get - HttpServer.cc:347
20240229 09:02:23.470655 UTC 24915 TRACE [onHttpRequest] http path=/api/data/get - HttpServer.cc:348
20240229 09:02:23.470801 UTC 24915 TRACE [runTaskInQueue] move task into queue - ConcurrentTaskQueue.cc:42
20240229 09:02:23.470836 UTC 24731 TRACE [queueFunc] got a new task! - ConcurrentTaskQueue.cc:65
20240229 09:02:23.471001 UTC 24915 TRACE [renderToBuffer] response(no body):HTTP/1.1 200 OK
content-length: 158
content-type: application/json; charset=utf-8
access-control-allow-credentials: true
access-control-allow-origin: <Hidden>

 - HttpResponseImpl.cc:707
20240229 09:02:25.313576 UTC 24912 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:02:25.385077 UTC 24912 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:02:25.385116 UTC 24912 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:02:25.385128 UTC 24912 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:02:25.657833 UTC 24913 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:02:25.730819 UTC 24913 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:02:25.730859 UTC 24913 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:02:25.730867 UTC 24913 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:02:43.470979 UTC 24729 TRACE [~CacheMap] CacheMap destruct! - CacheMap.h:161
20240229 09:02:43.471045 UTC 24729 TRACE [~CacheMap] CacheMap destruct! - CacheMap.h:161
20240229 09:02:43.471081 UTC 24729 TRACE [~CacheMap] CacheMap destruct! - CacheMap.h:161
20240229 09:02:43.471118 UTC 24729 TRACE [~CacheMap] CacheMap destruct! - CacheMap.h:161
20240229 09:02:43.471145 UTC 24729 TRACE [~CacheMap] CacheMap destruct! - CacheMap.h:161
20240229 09:02:55.313692 UTC 24912 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:02:55.388575 UTC 24912 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:02:55.388621 UTC 24912 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:02:55.388630 UTC 24912 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:02:55.658490 UTC 24913 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:02:55.738012 UTC 24913 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:02:55.738055 UTC 24913 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:02:55.738063 UTC 24913 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:03:24.082473 UTC 24915 TRACE [handleClose] connection closed, fd=78 - TcpConnectionImpl.cc:276
20240229 09:03:24.082507 UTC 24915 TRACE [handleClose] write buffer size: 0 - TcpConnectionImpl.cc:277
20240229 09:03:24.082473 UTC 24913 TRACE [handleClose] connection closed, fd=76 - TcpConnectionImpl.cc:276
20240229 09:03:24.082514 UTC 24913 TRACE [handleClose] write buffer size: 0 - TcpConnectionImpl.cc:277
20240229 09:03:24.082529 UTC 24913 TRACE [onConnection] conn disconnected! - HttpServer.cc:118
20240229 09:03:24.082529 UTC 24915 TRACE [onConnection] conn disconnected! - HttpServer.cc:118
20240229 09:03:24.082557 UTC 24915 TRACE [handleClose] to call close callback - TcpConnectionImpl.cc:292
20240229 09:03:24.082557 UTC 24913 TRACE [handleClose] to call close callback - TcpConnectionImpl.cc:292
20240229 09:03:24.082561 UTC 24913 TRACE [connectionClosed] connectionClosed - TcpServer.cc:201
20240229 09:03:24.082561 UTC 24915 TRACE [connectionClosed] connectionClosed - TcpServer.cc:201
20240229 09:03:24.082641 UTC 24915 TRACE [handleClose] connection closed, fd=77 - TcpConnectionImpl.cc:276
20240229 09:03:24.082646 UTC 24915 TRACE [handleClose] write buffer size: 0 - TcpConnectionImpl.cc:277
20240229 09:03:24.082654 UTC 24915 TRACE [onConnection] conn disconnected! - HttpServer.cc:118
20240229 09:03:24.082660 UTC 24913 TRACE [handleClose] connection closed, fd=74 - TcpConnectionImpl.cc:276
20240229 09:03:24.082664 UTC 24913 TRACE [handleClose] write buffer size: 0 - TcpConnectionImpl.cc:277
20240229 09:03:24.082670 UTC 24915 TRACE [handleClose] to call close callback - TcpConnectionImpl.cc:292
20240229 09:03:24.082671 UTC 24913 TRACE [onConnection] conn disconnected! - HttpServer.cc:118
20240229 09:03:24.082672 UTC 24915 TRACE [connectionClosed] connectionClosed - TcpServer.cc:201
20240229 09:03:24.082680 UTC 24913 TRACE [handleClose] to call close callback - TcpConnectionImpl.cc:292
20240229 09:03:24.082683 UTC 24913 TRACE [connectionClosed] connectionClosed - TcpServer.cc:201
20240229 09:03:24.082736 UTC 24913 TRACE [~Socket] Socket deconstructed:76 - Socket.cc:245
20240229 09:03:24.082736 UTC 24915 TRACE [~Socket] Socket deconstructed:78 - Socket.cc:245
20240229 09:03:24.082813 UTC 24913 TRACE [~Socket] Socket deconstructed:74 - Socket.cc:245
20240229 09:03:24.082824 UTC 24915 TRACE [~Socket] Socket deconstructed:77 - Socket.cc:245
20240229 09:03:24.082855 UTC 24912 TRACE [handleClose] connection closed, fd=75 - TcpConnectionImpl.cc:276
20240229 09:03:24.082864 UTC 24912 TRACE [handleClose] write buffer size: 0 - TcpConnectionImpl.cc:277
20240229 09:03:24.082873 UTC 24912 TRACE [onConnection] conn disconnected! - HttpServer.cc:118
20240229 09:03:24.082886 UTC 24912 TRACE [handleClose] to call close callback - TcpConnectionImpl.cc:292
20240229 09:03:24.082889 UTC 24912 TRACE [connectionClosed] connectionClosed - TcpServer.cc:201
20240229 09:03:24.082937 UTC 24912 TRACE [~Socket] Socket deconstructed:75 - Socket.cc:245
20240229 09:03:25.313798 UTC 24912 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:03:25.387629 UTC 24912 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:03:25.387667 UTC 24912 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:03:25.387676 UTC 24912 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:03:25.658600 UTC 24913 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:03:25.746352 UTC 24913 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:03:25.746391 UTC 24913 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:03:25.746399 UTC 24913 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:03:55.313893 UTC 24912 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:03:55.387386 UTC 24912 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:03:55.387454 UTC 24912 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:03:55.387482 UTC 24912 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:03:55.658698 UTC 24913 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:03:55.743083 UTC 24913 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:03:55.743123 UTC 24913 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:03:55.743131 UTC 24913 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:04:25.314001 UTC 24912 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:04:25.389970 UTC 24912 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:04:25.390017 UTC 24912 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:04:25.390027 UTC 24912 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:04:25.658847 UTC 24913 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:04:25.762248 UTC 24913 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:04:25.762296 UTC 24913 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:04:25.762319 UTC 24913 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:04:49.730472 UTC 24912 TRACE [newConnection] new connection:fd=74 address=172.104.20.247:61000 - TcpServer.cc:62
20240229 09:04:49.730531 UTC 24912 TRACE [TcpConnectionImpl] new connection:172.104.20.247:61000->138.68.65.191:443 - TcpConnectionImpl.cc:78
20240229 09:04:55.658911 UTC 24913 TRACE [sendWsData] send 0 bytes - WebSocketConnectionImpl.cc:73
20240229 09:04:55.748443 UTC 24913 TRACE [recvData] Received 28 bytes from lower layer - OpenSSLProvider.cc:536
20240229 09:04:55.748491 UTC 24913 TRACE [processApplicationData] Received 6 bytes from SSL - OpenSSLProvider.cc:747
20240229 09:04:55.748500 UTC 24913 TRACE [parse] data encoded! - WebSocketConnectionImpl.cc:291
20240229 09:05:06.782158 UTC 24915 TRACE [newConnection] new connection:fd=75 address=<Hidden>:61376 - TcpServer.cc:62
20240229 09:05:06.782206 UTC 24915 TRACE [TcpConnectionImpl] new connection:<Hidden>:61376->10.19.0.5:443 - TcpConnectionImpl.cc:78

And in stdout we noticed the following:

our-server: /home/our-user/our-server/drogon/trantor/trantor/net/inner/tlsprovider/OpenSSLProvider.cc:481: OpenSSLProvider::OpenSSLProvider(trantor::TcpConnection*, trantor::TLSPolicyPtr, trantor::SSLContextPtr): Assertion `ssl_' failed.
our-server: /home/our-user/our-server/drogon/trantor/trantor/net/inner/tlsprovider/OpenSSLProvider.cc:481: OpenSSLProvider::OpenSSLProvider(trantor::TcpConnection*, trantor::TLSPolicyPtr, trantor::SSLContextPtr): Assertion `ssl_' failed.
our-server: /home/our-user/our-server/drogon/trantor/trantor/net/inner/tlsprovider/OpenSSLProvider.cc:481: OpenSSLProvider::OpenSSLProvider(trantor::TcpConnection*, trantor::TLSPolicyPtr, trantor::SSLContextPtr): Assertion `ssl_' failed.

What might be the problem?

Edit: The IP 172.104.20.247 has been kept intentionally, it has been trying to connect before with a different IP, and I believe it is the one causing this crash.

Using Botan as TLS provider does not work

I ran it first time and it logged

BotanTLSConnectionImpl does not support sslConfCmds.

I disabled TLSv1.3 configuration, and ran it again, it doesn't log anything or respond to a GET request to index.html, it just hangs waiting for a response in the browser.

See this branch.

Edit: Manually entering the address https://localhost:8443 now shows the following in the log and still hangs

20230826 10:32:03.406258 UTC 84510 ERROR Unexpected TLS Exception: TLS record type had unexpected value - BotanTLSProvider.cc:169

HashUnitTest Hash5 Hash256 Faild

See the result in VS 2022
image

D:\DownLoads\trantor-master\trantor\unittests\HashUnittest.cc(12): error: Expected equality of these values:
  toHexString(md5("hello"))
    Which is: "604E0000FE2E00005D600000D5D70000"
  "5D41402ABC4B2A76B9719D911017C592"

D:\DownLoads\trantor-master\trantor\unittests\HashUnittest.cc(13): error: Expected equality of these values:
  toHexString(md5("trantor"))
    Which is: "37490000DBA1000034D30000ACCA0000"
  "95FC641C9E629D2854B0B60F5A51E1FD"

D:\DownLoads\trantor-master\trantor\unittests\HashUnittest.cc(28): error: Expected equality of these values:
  toHexString(sha256("hello"))
    Which is: "0000A7190000A86500006FA10000B2010000BA3B0000872D00007A1A000001C7"
  "2CF24DBA5FB0A30E26E83B2AC5B9E29E1B161E5C1FA7425E73043362938B9824"

D:\DownLoads\trantor-master\trantor\unittests\HashUnittest.cc(31): error: Expected equality of these values:
  toHexString(sha256("trantor"))
    Which is: "0000C1150000FF010000468B000022340000D1AD00001049000020A20000461D"
  "C72002E712A3BA6D60125D4B3D0B816758FBDCA98F2A892077BD4182E71CF6F5"

[FR] 32bit timestamp conversion

We already have trantor::Date::microSecondsSinceEpoch but it will be a pain in ass if I want seconds instead of microseconds.
It will be great if you can implement such function like trantor::Date::secondsSinceEpoch.

Add and expose enableRead()/disableRead(), startRead()/stopRead() functions

Just tried to use and implement simple tcp proxy server: https://github.com/gonwan/toys/tree/master/webframework-benchmark/trantor-proxy
The trantor library is super fast, and one api issue. For applications like proxy(tunnel, replay etc...), it's better to have the control of socket readability, which is supported by moduo: https://github.com/chenshuo/muduo/blob/a55abc2158d381fced580d7a6c66be06b771c5da/examples/socks4a/tcprelay.cc#L21 . Please add/expose these functions if possible.

Throw on failure instead of exiting

If there are socket errors like if the port fails to bind , could Trantor throw an exception rather than exiting? In this case, the calling application could try again with a different port. Or if the exception isn't caught, then it would fail with a visible error and stack trace rather than just a message in the log.

OpenSSL TLS provider not working correctly

When a HTTPs response with a large content body is sent, then not all bytes will be transferred and the connection will hang indefinitely until it reaches a timeout.

Example request:

curl -X 'GET' -k
'https://192.168.200.232/v2/endpoint'
-H 'accept: application/json'
-H 'Authorization: Basic dGVzdDo=' --trace-time -v
Note: Unnecessary use of -X or --request, GET is already inferred.
15:44:55.711265 * Trying 192.168.200.232:443...
15:44:55.717252 * Connected to 192.168.200.232 (192.168.200.232) port 443 (#0)
15:44:55.719318 * ALPN, offering h2
15:44:55.719346 * ALPN, offering http/1.1
15:44:55.719472 * TLSv1.0 (OUT), TLS header, Certificate Status (22):
15:44:55.719503 * TLSv1.3 (OUT), TLS handshake, Client hello (1):
15:44:55.761049 * TLSv1.2 (IN), TLS header, Certificate Status (22):
15:44:55.761226 * TLSv1.3 (IN), TLS handshake, Server hello (2):
15:44:55.761775 * TLSv1.2 (IN), TLS header, Finished (20):
15:44:55.761849 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:55.761886 * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
15:44:55.761913 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:55.761999 * TLSv1.3 (IN), TLS handshake, Certificate (11):
15:44:55.763293 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:55.763344 * TLSv1.3 (IN), TLS handshake, CERT verify (15):
15:44:55.763410 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:55.763449 * TLSv1.3 (IN), TLS handshake, Finished (20):
15:44:55.763489 * TLSv1.2 (OUT), TLS header, Finished (20):
15:44:55.763513 * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
15:44:55.763558 * TLSv1.2 (OUT), TLS header, Supplemental data (23):
15:44:55.763591 * TLSv1.3 (OUT), TLS handshake, Finished (20):
15:44:55.763633 * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
15:44:55.763656 * ALPN, server did not agree to a protocol
15:44:55.763675 * Server certificate:
15:44:55.763690 * subject:
15:44:55.763699 * start date: Oct 4 08:46:14 2023 GMT
15:44:55.763707 * expire date: Sep 10 08:46:14 2123 GMT
15:44:55.763722 * issuer:
15:44:55.763752 * SSL certificate verify result: self-signed certificate in certificate chain (19), continuing anyway.
15:44:55.763795 * TLSv1.2 (OUT), TLS header, Supplemental data (23):
15:44:55.763831 > GET /v2/endpoint HTTP/1.1
15:44:55.763831 > Host: 192.168.200.232
15:44:55.763831 > User-Agent: curl/7.81.0
15:44:55.763831 > accept: application/json
15:44:55.763831 > Authorization: Basic dGVzdDo=
15:44:55.763831 >
15:44:55.776094 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:55.776234 * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
15:44:55.776353 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:55.776497 * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
15:44:55.776742 * old SSL session ID is stale, removing
15:44:56.901714 * TLSv1.2 (IN), TLS header, Supplemental data (23):
15:44:56.910324 * Mark bundle as not supporting multiuse
15:44:56.910420 < HTTP/1.1 200 OK
15:44:56.910559 < content-length: 56531
15:44:56.910639 < content-type: application/json; charset=utf-8
15:44:56.910772 < server: backend-api/0.1.0.6822
15:44:56.910938 < access-control-allow-origin: *
15:44:56.911114 < date: Mon, 27 Nov 2023 14:44:52 GMT
15:44:56.911246 <
{"json_content_that_will_be_cut_off
15:44:56.912609 * TLSv1.2 (IN), TLS header, Supplemental data (23):
^C ////// <<<< timeout

Is it possible that the last chunk of data is not flushed to the output?

What is Tensor in Logger.h?

Tensor shows up in Logger.h, but can't find it anywhere else.

Is it old name of trantor or something?

#define LOG_DEBUG_IF(cond) \
if ((Tensor::Logger::logLevel() <= Tensor::Logger::kDebug) && (cond)) \
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kDebug, __func__) \
.stream()
#define LOG_INFO_IF(cond) \
if ((Tensor::Logger::logLevel() <= Tensor::Logger::kInfo) && (cond)) \
Tensor::Logger(__FILE__, __LINE__).stream()
#define LOG_WARN_IF(cond) \
if (cond) \
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kWarn).stream()
#define LOG_ERROR_IF(cond) \
if (cond) \
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kError).stream()
#define LOG_FATAL_IF(cond) \
if (cond) \
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kFatal).stream()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.