Releases: volt-software/Ichor
Releases · volt-software/Ichor
v0.4.0
New Features / Significant Changes
- Implement almost entire Etcd v2 API (user auth, roles, permissions)
- Expand redis API implementation (strlen, multi, discard, exec, info)
- Reduce memory usage for events significantly (>50%)
- Reduce memory usage for services
- Introduce non-atomic shared_ptr
- Support requesting dependencies of the same type multiple times but with different properties (e.g. two IHttpConnection's to different addresses)
- Support custom HTTP route matchers
- Introduce an Ichor RegexRouteMatcher that supports capture groups for parsing e.g.
/users/{id}?{queryParam1}={valueParam1}
- Introduce an Ichor RegexRouteMatcher that supports capture groups for parsing e.g.
- Implement Small Buffer Optimization in Ichor::Any
- Support converting Ichor::Any type and values to string for logging contents of Properties
- Add Raspberry Pi model specific optimization flags
- Add benchmark numbers on Raspberry Pi Model 4B
- Add
_FORTIFY_SOURCE=3
and other security related flags on non-windows builds when using hardening - Improve various compile/link modes, e.g. using libcpp instead of libstdc++ or creating a statically linked musl-aarch64-mimalloc build.
- Support services having a priority lower than the default dependency priority, effectively enabling some control over which services get initialized first.
- Have coroutines use the same priority for events as the services that create them
Third-party Libraries
- Fork and update Mimalloc to 2.1.2
- Forked because of this issue.
- Allows using mimalloc with ASAN as well as on the combination of musl, aarch64
- Use mimalloc's secure mode when hardening is turned on, even for release builds.
- Update spdlog to v1.13.0
- Update fmt to 10.2.1
- Update Catch to 3.5.2
- Update sole to 1.0.5
- Update glaze to 2.0.6
- Introduce CTRE 3.8.1
- Introduce ankerl's unordered_dense 4.40, replacing std::unordered_map and abseil::btree_map entirely.
- Remove abseil as a possible dependency (users are free to re-introduce it in their own projects, of course)
Bug Fixes
- Fix bug when sending multiple messages with HttpConnectionService
- Fix data race with multiple threads creating services without dependencies
- Fix data race in coroutine IO implementation
- Fix bug in EventStatisticsService where collected events would be thrown away because a coroutine was not being run to completion
- Fix bug where iterators to event interceptors might get invalidated by modifying the list of interceptors inside of an event intercept handler
- Fix bug where realtime example would always try to re-enable SMT if option to disable it was missing
v0.3.0
Major Changes
- Support Aarch64
- Support musl
- Add https support (not yet for websockets)
- Dockerfile based builds
- Support some async file I/O a la rust's tokio
- Add async mutex
Breaking Changes
None
The most exciting feature addition is the async file I/O, which emulates rust's tokio's async functions:
// enqueue reading the file on another thread and co_await its result
// not using auto to show the type in example. Using auto would be a lot easier here.
tl::expected<std::string, Ichor::FileIOError> ret = co_await async_io_svc->read_whole_file("AsyncFileIO.txt");
if(!ret || ret != "This is a test") {
fmt::print("Couldn't read file\n");
co_return {};
}
// enqueue writing to file (automatically overwrites if already exists)
tl::expected<void, Ichor::FileIOError> ret2 = co_await async_io_svc->write_file("AsyncFileIO.txt", "Overwrite");
if(!ret2) {
fmt::print("Couldn't write file\n");
co_return {};
}
ret = co_await async_io_svc->read_whole_file("AsyncFileIO.txt");
if(!ret || ret != "Overwrite") {
fmt::print("Couldn't read file\n");
co_return {};
}
More information on the async I/O can be found in the docs.
Full Changelog: v0.2.0...v0.3.0
v0.2.0
Major Changes
- Fully support Windows, partially support OSX
- Add Redis service support
- Add the Task class as a lightweight way to use coroutines
- Added constructor injection support
- Allow coroutines in start/stop methods for AdvancedService
Breaking Changes
- Renamed LoggerAdmin to LoggerFactory
- Renamed ClientAdmin to ClientFactory
- Refactored timers, now requires the TimerFactoryFactory
- Services do not automatically have access to DependencyManager (to cut amount of header includes)
- Changed a lot of argument types from points to references or to the new NeverNull class
- Renamed Service to AdvancedService
- Removed SerializerAdmin in favour of directly requesting serializers for types
Full Changelog: v0.1.0...v0.2.0
v0.1.0
Main Changes
- Improve developer ergonomy:
- Remove polymorphic allocator in favour of mimalloc
- Change most pointers to references
- Compiler support expanded:
- Support clang 14 and up
- Support gcc 11.3 and up
- Implement
co_await
:- new AsyncGenerator class
- Used in timers, RunFunctionEvent, http classes
- Improve CI pipeline
- Support added for configurable event queues
- Multimap based
- Sdevent based
- User-defined ones
- Optionally use google abseil
Examples
co_await
Ichor now supports using co_await to wait on a response on HTTP requests:
auto toSendMsg = _serializationAdmin->serialize(PingMsg{_sequence});
HttpResponse &response = *co_await _connectionService->sendAsync(HttpMethod::post, "/ping", {}, std::move(toSendMsg)).begin();
if(response.status == HttpStatus::ok) {
auto msg = _serializationAdmin->deserialize<PingMsg>(response.body);
co_return msg;
} else {
co_return std::unique_ptr<PingMsg>{};
}
For more example code, please look at the ping pong example.
Different queue implementations
To instantiate the Multimap based queue:
#include <ichor/event_queues/MultimapQueue.h>
using namespace Ichor;
int main(int argc, char *argv[]) {
// ...
auto queue = std::make_unique<MultimapQueue>();
auto &dm = queue->createManager();
// ...
}
And the sdevent based one:
#include <ichor/event_queues/SdeventQueue.h>
using namespace Ichor;
int main(int argc, char *argv[]) {
// ...
auto queue = std::make_unique<SdeventQueue>();
auto &dm = queue->createManager();
dm.store(&dm, std::memory_order_release);
auto *loop = queue->createEventLoop();
// ...
queue->start(DoNotCaptureSigInt);
int r = sd_event_loop(loop);
// ...
}