Ichor Versions Save

C++20 Microservice Bootstrapping Framework

v0.4.0

3 months ago

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}
  • 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

6 months ago

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: https://github.com/volt-software/Ichor/compare/v0.2.0...v0.3.0

v0.2.0

1 year ago

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: https://github.com/volt-software/Ichor/compare/v0.1.0...v0.2.0

v0.1.0

1 year ago

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);
    // ...
}

v0.0.1

3 years ago

First alpha release of Ichor.