D++ 10.1: Faster, Smarter, and Coroutine-Powered 🚀
D++ 10.1 is here, and it's bringing some serious upgrades to your Discord bot development experience. Coroutines are now the default, making asynchronous programming smoother and more modern. If you're not ready to dive into coroutines just yet, you can still disable them with -DDPP_NO_CORO=ON
. The threading model has been completely overhauled with a reactor pattern and central thread pool, boosting performance across the board. There’s also a brand-new socket engine that intelligently picks the best available method (epoll
, kqueue
, or poll
) based on your OS, improving efficiency for high-throughput bots.
Beyond the under-the-hood improvements, you’ll find new coroutine-powered helper functions for message handling (co_send
, co_reply
), expanded event data like user_id
on reactions, and a new constructor for dpp::cluster
for lightweight webhook-based applications. Tons of bugs have been squashed, from lingering memory leaks to connection retries, ensuring a more stable experience. If you're still using the old _sync
functions, now’s the time to migrate—those are officially gone. Whether you’re running a small community bot or a high-scale application, this release makes D++ more powerful, efficient, and developer-friendly. Upgrade today and enjoy a faster, cleaner codebase! 🚀
The changelog is listed below:
Release Changelog
💣 Breaking Changes
- Coroutines are now default enabled. To disable them and only use C++17 features, use
-DDPP_NO_CORO=ON
cmake flag (#1368) - Updated
dpp::role
comparison operators to now consider role IDs (#1333) - Change
event_dispatch_t::from
member variable toevent_dispatch_t::from()
method - New threading model, using the reactor pattern and a central thread pool.
- Support for "socket engines", which are reactors containing support for
epoll
,kqueue
orpoll
depending on what your OS supports. dpp::timer
now internally uses astd::priority_queue
and is much more efficient especially with large (hundreds, thousands) numbers of active timersdpp::sync
and_sync
function are removed. They have been marked deprecated for two years now. You should migrate to coroutines instead.
✨ New Features
- Added
user_id
tomessage_reaction_add_t
(#1376) - Add coroutine support functions to
message_create_t
(co_send
,co_reply
) (#1357) - Socket engine stats functions (#1353)
dpp::cluster
now has a constructor with no parameters, which can be used when using the cluster purely for its reactor, e.g. for a purely webhook based application
🐞 Bug Fixes
- Detect c++17 to define DPP_NO_CORO at the point of usage (#1378)
- Fix C4245 warning on MSVC (#1367)
- Make sure write events go out as soon as they can (#1354)
- Large https request body could not be sent (#1352)
- Thread safety for event objects (10.1 only) (#1350)
- Coro timers ez pz lemon squeezy (#1351)
- Make new constructor for cluster explicit
- Docs: update documentation examples to use
event.from()
andevent.owner
unique_ptr
on g++-8 needs to knowsizeof()
z_stream
up front, so we must use a raw ptr 😦- Immediately delete fds that want deletion after we are done firing their events rather than
prune()
loop fix: replace fds that already exist in the set. emplace would fail. - Don't store the event ptrs in the kevent/epoll udata, this can end up with dangling ptrs in events
- Ensure heirarchy correctly calls the various inherited functions. todo: refactor this mess
- Fix for runaway cpu usage due to
connect()
retry - Fix fd and memory leak in httpsclient
- Fix reconnection of shards by creating new shards on reconnect, with a management timer to handle reconnections to stop reconnect storms
- Https request queues still need a removals queue, it can be simplified but needs to still exist, there is a chicken-and-egg situation with the pointer for the request
- Segfault when calling read on an invalid fd
- Prevent concurrent
on_disconnect()
- Fix
BUILD_VOICE_SUPPORT=OFF
static build (#1338) - Fixes for poll on Windows
- Fixes for cluster destructor on FreeBSD
- Fix kqueue to actually work on FreeBSD
- Add auto retry to failed connect, fixes failed unit tests
- Fix http(s) requests with 0 content length timing out
- Fix role edit/role delete unit tests
- dl.dpp.dev was not downloading rpms any more (#1335)
- Fix some httpsclient stuff
- Fix namespace include in cmakelists for mlspp, backport of mls++ fix (#1331)
- Two segmentation faults in
cluster::guild_edit_member
andcluster::tick_timers
/cluster::shutdown
(#1326) - FreeBSD port build issues (#1325)
- Fix/sslclient-spinlock (#1339)
- Fix/voice socketengine (#1337)
♻ Refactoring
- Remove some deprecated and unused fields
- Remove
sync.h
- Remove
dpp::sync
- Remove raw pointers from dns code
- Make overridden sslclient stuff have override keyword, tidy up zlib stuff
- Eliminate raw pointers from timer code
- Magic numbers in discordclient
- Remove thread pool from request queue, run it off
dpp::timer
instances instead - Remove nonblocking bool, as all sockets are always now nonblocking
- Remove
dpp::sync
from unit tests, we no longer test it - Remove jthread, C++20 only
📚 Documentation
- Fix codacy badge (#1375)
- Missing comment blocks
- New webhook example
- Document various new functions
- Redo thread model dot
- Updated checking-permissions page and a view functions (#1336)
- Document
socket_engine_base
📜 Miscellaneous Changes
- Tweaks and fixes to scripts and docs to support 10.1 (#1365)
- Don't always run php for
DPP_CORO
(#1363) - Make
event.from
safe in threads - Fix; when putting events into the thread pool work queue, we must take a copy of the cluster ptr, as the client ptr may be invalid by the time the event is triggered (shards now get reallocated)
- Split out zlib stuff to its own file
- Move some things into constexpr constants
- Tidy up casting in decompression code
- Call
on_disconnect
in more situations so we can properly handle dead sockets - adjust version to 10.1
- Catch exceptions on reconnect
- Voice session reconnect
- Tidy up shard startup
- Audio works if user joins 2nd
- Audio isn't being heard, dont know why yet
- warning fixes
- Improve threading
- Properly mutex everything
- we dont need to check for epoll removal failure, if it fails its already not in the set
- Destroy thread for socket loop before trying to destroy anything that may be within it
- Dont resize the
ke_list
- Mutexing of timer list
- Safety check handlers
- Sanity checks
- Errors were missing part of the url
- Some unit tests improvements
- Always populate even on timeout
- Dont let
request_verb
go out of scope sleep()
shouldnt be used, instead usestd::this_thread::sleep_for(std::chrono::seconds(6))
terminating.notify_all
is C++20- Unit test no longer runs forever
- Make poll ctor not protected
- Put websocket events into the work queue
- no longer any need for
out_queue
-> goes into the main thread pool - https client/queues migration to socketengine
- Socket engine basics
👷 Build/CI
- OSX now only tests on clang15 (#1345)
- Macos version will now always be 15
- Removed pkg-config from brew as no longer needed
- Force pkgconf unlink for brew