dolittle/Runtime
38.6
Weak · 21 September 2026
44k
lines of production code
C#
primary language
3
measurements over time
What this system is
This system is the Dolittle Runtime, a .NET-based event-driven platform that manages multi-tenant event ingestion, storage, and processing. It provides core capabilities for committing and fetching events via gRPC and WebAPI, handling aggregate root state, and executing event handlers through an actor-based architecture with partitioned concurrency. The runtime includes a CLI and web UI for management, alongside comprehensive observability features like OpenTelemetry and Prometheus metrics.
How it got here
2017–2020 — Event store and runtime foundation
69 changes.
This period established the core Dolittle Runtime architecture, focusing on the MongoDB-backed event store with support for partitioned streams, sparse logs, and optimistic concurrency. It introduced foundational services for tenancy, execution context, and microservice discovery, while implementing the Event Horizon for cross-tenant event streaming. The work also included the initial release of the Management UI and extensive test coverage to validate the new processing pipelines and data models.
2021 — CLI tooling and embedding infrastructure
106 changes.
This period focused on introducing the Dolittle CLI for runtime management and expanding the embedding processing pipeline with robust multi-tenant support. Significant work also went into establishing reverse call communication infrastructure and comprehensive test coverage for event handling and state transitions.
2022–2024 — Runtime architecture and event processing overhaul
80 changes.
This period focused on a comprehensive rewrite of the runtime's core infrastructure, introducing a tenant-scoped dependency injection system, unified configuration, and a new gRPC hosting layer. Significant effort was dedicated to redesigning the event store and stream processing engine to support partitioned concurrency, actor-based resilience, and background database migrations. The work also established robust observability through OpenTelemetry and Prometheus, alongside extensive integration testing to validate the new architectural components.
Features
Actor grain registration and safe spawning utilities
The Actors module now provides structured support for registering and managing actor grains via the \GrainAttribute\ and \TenantGrainAttribute\, which automatically wire up client types and grain definitions in the dependency injection container. A new \ICreateProps\ implementation (\CreateProps\) allows actors to be instantiated using the tenant-specific service provider, ensuring proper dependency injection. Additionally, \ContextExtensions\ introduces safe spawning methods (\TrySpawn\*\) and error-handling wrappers for \ReenterAfter\ operations, allowing developers to spawn actors and handle asynchronous messages without unhandled exceptions crashing the actor context.
Source/Actors · high confidence
Add CLI command to list running Event Handlers
Users can now run 'dolittle runtime eventhandlers list' to view the status of all running Event Handlers. The command supports filtering by Tenant and displays output in either a simple table (showing alias, scope, partition status, and health) or a detailed view (including the last successful processing time). Output can be formatted as JSON or a human-readable table.
Source/CLI/Runtime/EventHandlers/List · high confidence
Add CLI command to list runtime event types
Users can now discover and view registered Event Types in a Runtime using the new \dolittle runtime eventtypes\ command and its \list\ subcommand. The CLI connects to the Runtime's management service to fetch all Event Types, displaying them in a simple table (showing the alias or identifier) or a detailed view (showing alias and ID), with support for JSON output.
Source/CLI/Runtime/EventTypes · high confidence
Add CLI command to retrieve Event Handler status
Users can now run \dolittle runtime eventhandlers get\ to inspect the current state of a specific Event Handler. The command accepts an Event Handler identifier (or alias) and an optional \--tenant\ filter, then displays the handler's position, success/failure status, and detailed metrics such as failure reasons, retry times, and processing attempts. Output is provided in both simple table and detailed JSON formats, with specific handling for partitioned versus unpartitioned handlers.
Source/CLI/Runtime/EventHandlers/Get · high confidence
Add CLI command to view committed aggregate events
Users can now retrieve committed aggregate events for a specific aggregate root instance using the new 'dolittle runtime aggregates events' CLI command. The command accepts the aggregate root identifier and event source ID, with an optional tenant filter, and displays the results in either a simple table (showing version, sequence number, and event type) or a detailed view (including public status and occurrence time). In table mode, only the last 10 events are shown by default.
Source/CLI/Runtime/Aggregates/Events · high confidence
Add output format selection for CLI
A new OutputType enum has been introduced to allow users to specify whether CLI command results should be displayed as a table or in JSON format.
Source/CLI/Options · high confidence
Add support for scoped hosts with isolated DI containers
Users can now register hosted services in an isolated dependency injection container using the new \AddScopedHost\ extension on \IHostBuilder\. This allows services configured within the scoped host to remain invisible to the parent host, while the parent host still manages the lifecycle (start/stop) of those hosted services. The implementation introduces a \ScopedHostBuilder\ that proxies hosted services into the parent container, ensuring they resolve from a dedicated child service provider created via \ICreateServiceProvidersForScopedHosts\.
Source/Hosting · high confidence
Add web host with Swagger UI and health check endpoints
The web server layer now includes a dedicated health check endpoint at /healthz (reporting on the Proto.Actor cluster status) and an integrated Swagger UI for API exploration. The web host is configured to listen on port 8001 by default, with this setting managed via the new WebServerConfiguration class, and uses Kestrel for serving requests.
Source/Server/Web · high confidence
Added Event Types management service
Introduced a new gRPC service for managing event types, allowing users to retrieve a complete list of all registered event types. The implementation includes the \EventTypesService\ which exposes a \GetAll\ endpoint to fetch event type aliases and identifiers, along with corresponding logging extensions to track retrieval operations and failures.
Source/Events/Management · high confidence
Added debugging script for committing events via gRPC
A new shell script (commit-event.sh) and README have been added to the Debugging directory to help developers interact with the Runtime during development. The script uses grpcurl to send a sample event commit request to the EventStore service on localhost:50053, allowing users to test event ingestion without relying on the SDK.
Debugging · high confidence
Added doughnut and line chart components to the Management UI
The Management UI now includes two new reusable chart components: a doughnut chart and a line chart, both powered by Chart.js. The doughnut chart displays partition data with 'Success' and 'Failing' categories, while the line chart visualizes event counts over time for 'CustomerCreated' and 'OfferAccepted' metrics. These components are registered as global Aurelia custom elements, making them available for use throughout the application's interface.
Source/ManagementUI/features/components · high confidence
Added event processing architecture diagrams
New PlantUML diagrams have been added to the Diagrams folder to visualize the event processing system. The EntityRelations diagram documents the data model and relationships between core entities such as Filter, EventHandler, StreamProcessor, and EventProcessor. The StreamProcessingStateMachine diagram illustrates the lifecycle states of the stream processor, including FetchingEvent, Processing, Waiting, Retrying, and Stopping, along with the transitions between them.
Diagrams · high confidence
Added file-based configuration serialization support
The CLI now includes a new \ISerializer\ interface and its \Serializer\ implementation to handle deserializing JSON configuration files from the file system. This feature integrates with the existing content serialization logic and registers the necessary services (including a \PhysicalFileProvider\ based on the CLI's working directory) via \ServiceCollectionExtensions.AddConfigurationFiles\, enabling the CLI to read and parse configuration data from local files.
Source/CLI/Configuration · high confidence
Added integration benchmark infrastructure
Added a new benchmarking project under Integration/Benchmarks that uses BenchmarkDotNet to measure Runtime performance. The setup includes a base Job class (JobBase) that automatically starts a local Runtime server with a configurable number of tenants before each benchmark run and cleans up the environment afterward, along with a Program entry point to execute the benchmarks.
Integration/Benchmarks · high confidence
Added local MongoDB replica set development environment
A new Docker-based development environment for MongoDB has been added to the Events.Store.MongoDB module. This includes a Dockerfile based on the official mongo:7.0 image, a JavaScript script to automatically initiate a single-server replica set (rs0) on startup, and a shell script to build and push the custom image. This allows developers to run a local MongoDB instance that matches the replica set requirements of the application, simplifying local testing and debugging.
Source/Events.Store.MongoDB/Development · high confidence
Added stream processor status conversion logic
Introduced the IConvertStreamProcessorStatuses interface and its implementation to translate internal stream processor states into the protobuf contract representation. This change enables the system to expose detailed status information for both partitioned and unpartitioned stream processors, including specific failure reasons, retry counts, and timestamps, making this data available for monitoring and management purposes.
Source/Events/Processing/Management/StreamProcessors · high confidence
Attribute-based service registration for tenant and non-tenant services
The dependency injection system now supports registering services based on custom attributes. New classes in the \Source/DependencyInversion/Attributes\ directory (\ServicesBuilderForTypesWith\, \TenantServicesBuilderForTypesWith\, and their static factory counterparts) enable the framework to discover types marked with specific attributes and automatically register them as either non-tenant or tenant-specific services. This allows developers to declaratively control service registration by applying attributes to their classes, with the system handling the discovery and binding to the appropriate \IServiceCollection\ or tenant-scoped collection.
Source/DependencyInversion/Attributes · high confidence
CLI now supports parsing Concept types for Guid, string, and ulong arguments
The CLI's command-line argument parsing has been extended to handle 'Concept' types (implementations of ConceptAs) for Guid, string, and ulong base values. This is achieved by introducing a generic ConceptParser base class and specific implementations (GuidConceptParser, StringConceptParser, UlongConceptParser) that integrate with the McMaster.Extensions.CommandLineUtils framework. Users can now pass these specific concept types as command-line arguments, with the CLI automatically parsing the string input into the corresponding base type and wrapping it in the concept class.
Source/CLI/Options/Parsers/Concepts · high confidence
CLI support for listing and inspecting Aggregate Roots
The CLI now includes a new 'dolittle runtime aggregates' command group, enabling users to manage and inspect Aggregate Roots directly from the terminal. This update introduces the 'list' subcommand, which displays registered Aggregate Roots in either a simple or detailed view (including aliases and instance counts) and supports filtering by Tenant. The implementation adds the necessary runtime infrastructure, including a management client for communicating with the Runtime service, an ID resolver that allows referencing Aggregate Roots by either their unique ID or human-readable alias, and specific error handling for scenarios where roots or events cannot be retrieved.
Source/CLI/Runtime/Aggregates · high confidence
CLI support for managing Event Handlers
The CLI now includes a new 'eventhandlers' command group that allows users to list, retrieve, and reprocess events for registered Event Handlers. This change introduces the underlying runtime services and management client required to query Event Handler statuses, resolve identifiers from aliases, and execute reprocessing tasks against the runtime microservice.
Source/CLI/Runtime/EventHandlers · high confidence
CLI support for parsing microservice host:port addresses
The CLI now includes a dedicated parser for microservice addresses, allowing users to specify services using a host:port format (e.g., 'localhost:5000' or '\[::1\]:8080'). This change introduces a new exception, InvalidMicroserviceAddress, which is thrown when the provided address does not match the expected pattern, ensuring that only valid microservice endpoints are accepted in command-line arguments.
Source/CLI/Options/Parsers/Microservices · high confidence
CLI support for replaying event handler events
The CLI now includes commands to trigger event handler replays, allowing users to reprocess events via \dolittle runtime eventhandlers replay all\ (to reprocess all events) or \dolittle runtime eventhandlers replay from \<position\>\ (to reprocess from a specific stream position, optionally targeting a specific tenant). These commands resolve the target event handler by ID or alias and execute the replay against the connected runtime.
Source/CLI/Runtime/EventHandlers/Replay · high confidence
Client build results are now queryable via the Management API
The Client module now exposes a new management service that allows users to retrieve build results for connected heads. This change introduces a set of internal data models (BuildResult, ArtifactBuildResult, BuildResults) to represent build outcomes, along with an IBuildResultsForHeads service to store and retrieve them. A new gRPC endpoint, GetBuildResults, has been added to the ClientService, enabling external consumers to fetch the aggregated build status (including event types, aggregate roots, handlers, projections, embeddings, and filters) via the management interface.
Source/Client · high confidence
Event Handler Management API implementation
The Event Handlers management service is now implemented, exposing gRPC endpoints to list all event handlers, retrieve details for a specific handler, and trigger event reprocessing (either from a specific stream position or all events). This location provides the service implementation, failure ID definitions for specific error states (such as unregistered handlers or invalid reprocessing positions), exception-to-failure conversion, and structured logging for these management operations.
Source/Events/Processing/Management/EventHandlers · high confidence
Event Horizon consumer connection metrics and observability
The Event Horizon consumer connection layer now exposes comprehensive metrics for connection attempts, successes, failures, and event handling throughput. These metrics are collected via both Prometheus and OpenTelemetry counters, allowing users to monitor connection health, subscription failures (such as missing consent or arguments), and event processing performance in real-time.
Source/EventHorizon/Consumer/Connections · high confidence
Event type registration and management surface
The Events module now supports the registration and management of event types. A new gRPC service surface (EventTypesService) exposes a Register operation, allowing clients to register event types identified by an Artifact ID and an optional alias. Internally, the system uses a singleton EventTypes store to track these registrations, with dedicated types (EventType, EventTypeAlias, EventSourceId) to model the metadata. Additionally, an ActorPropsAdder registers the necessary actor dependencies for event processing, and mapping extensions facilitate the conversion of committed events from protobuf representations.
Source/Events · high confidence
Initial implementation of GDPR redaction capability
Introduces a new Redaction event type that allows users to specify which properties of existing events should be redacted based on their EventSourceId. The system now identifies redaction requests by checking if the event type ID starts with a specific prefix ('de1e7e17-bad5-da7a') rather than matching an exact ID, and prevents the redaction of other redaction events to preserve audit logs.
Source/Events/Store/Redactions · high confidence
Initial release of the Dolittle CLI tool
Introduces the Dolittle CLI, a command-line interface for managing Dolittle runtime environments. The tool provides a structured command system built on McMaster.Extensions.CommandLineUtils, featuring a base command class that supports output formatting in both table and JSON modes. It includes specific parsers for handling aggregate identifiers (supporting both IDs and aliases) and semantic versions, along with configuration file parsing and dependency injection setup for runtime services.
Source/CLI · high confidence
Initial release of the Dolittle Management UI frontend
The Management UI frontend is now available, providing a web-based interface for managing the Dolittle runtime. This release introduces the core application shell with a tenant selector, a navigation sidebar, and a router configured for several management sections including General (Overview, Metrics, Logs), Connections (Runtimes, Heads), Event Store, and TimeSeries. The UI integrates with gRPC services to display live data, such as connected heads and tenant lists, and includes configuration for linting, formatting, and build tooling.
Source/ManagementUI/features · high confidence
Initial repository structure and build configuration
The repository is initialized with the core project structure for the Dolittle Runtime, including a solution file defining source projects (such as Artifacts, EventHorizon, Events.Store, and Server) and their corresponding specification tests. Build configuration is established through centralized props files (default.props, specs.props, tests.props) targeting .NET 9.0, alongside an .editorconfig for code formatting and a .dockerignore to streamline container builds. The project also includes a CHANGELOG.md starting at version 9.9.0, a comprehensive README with Docker and development instructions, and TypeScript configuration files for tooling.
(repo-wide) · high confidence
Initial tenancy support with tenant enumeration and multi-tenant action execution
The Runtime now includes a foundational tenancy system that allows configuration and enumeration of tenants via the 'tenants' configuration section. Users can retrieve the list of configured tenants through a new gRPC service (TenantsService) and perform actions across all tenants using the IPerformActionsForAllTenants interface, which supports synchronous and asynchronous callbacks with per-tenant service provider access. The system also defines a TenantNotConfigured exception for scenarios where a specific tenant is accessed but not defined in the configuration.
Source/Tenancy · high confidence
Introduce Aggregate Root model and management APIs for the Event Store
The Event Store now exposes a formal Aggregate Root model, including types for identifiers, aliases, and versions, along with services to register roots and fetch their instances scoped by tenant. A new management API allows administrators to query all aggregate roots, retrieve specific ones, and fetch the committed events for a given event source, providing better visibility into the state of aggregates within the system.
Source/Events/Store · high confidence
Introduce Artifact model with type-safe identifiers
The Artifacts module now provides a core domain model for managing artifacts, defined by a unique identifier, a type, and a generation counter. ArtifactId and ArtifactType are implemented as strong types wrapping Guids, with ArtifactId supporting implicit conversions from both Guid and string for easier usage. ArtifactGeneration wraps a uint to track versioning, and the Artifact record ties these concepts together, offering a static factory method to create new, first-generation artifacts.
Source/Artifacts · high confidence
Introduce Protobuf serialization extensions for platform and execution types
This change adds a new set of extension methods in the Protobuf layer to serialize and deserialize domain concepts and execution context data to and from gRPC contracts. Specifically, it introduces converters for platform identifiers (ApplicationId, CustomerId, MicroserviceId, TenantId), names, and Environment strings, as well as a custom SemVer 2.0 Version type that handles pre-release strings and build numbers. It also provides mappings for ExecutionContext fields—including SpanId, Claims, and Version—ensuring that runtime execution details are correctly transmitted over the wire.
Source/Protobuf · high confidence
Introduce microservice configuration and address models
Added new data models and configuration structures to support microservice discovery and connectivity. This includes the MicroserviceAddress record for combining host and port, strongly-typed MicroserviceHost and MicroservicePort records with implicit string/int conversions, and a MicroservicesConfiguration class that maps microservice GUIDs to their specific host and port configurations under the 'microservices' configuration key.
Source/Microservices · high confidence
Introduce ping-based keepalive and metrics for reverse call connections
The ReverseCalls service now supports keeping gRPC duplex streaming connections alive by automatically sending periodic ping messages to the client. This is implemented via the new IKeepConnectionsAlive interface and PingedConnection, which schedules pings using ICallbackScheduler and cancels the connection if pongs are not received within a configured timeout. The system also introduces comprehensive metrics collection (IMetricsCollector) for stream activity (writes, reads, bytes, wait times) and keepalive status (pings sent, pongs received, timeouts), exposed via both Prometheus and OpenTelemetry. Additionally, the ReverseCallStreamWriter now handles ping injection and metrics recording, with a factory (ReverseCallStreamWriterFactory) that can optionally use an Actor-based implementation based on configuration.
Source/Services/ReverseCalls · high confidence
Introduce service callback scheduling with metrics
Added a new callback scheduling system in the Services/Callbacks module that allows registering callbacks to run at specified intervals. The implementation includes a high-priority background scheduler loop, grouped callback execution, and cancellation support via IDisposable. It also introduces comprehensive metrics collection for registered, called, failed, and missed callbacks, exposing data via both Prometheus and OpenTelemetry counters.
Source/Services/Callbacks · high confidence
Introduces CLI JSON serialization with ConceptAs support
The CLI now includes a dedicated serialization layer that registers a custom JSON converter for handling \ConceptAs\<T\>\ types, ensuring they are correctly serialized and deserialized. This change adds the \ConceptConverter\ and a \Serializer\ implementation wired via \ServiceCollectionExtensions\, replacing previous ad-hoc or missing serialization logic within the CLI scope.
Source/CLI/Serialization · high confidence
Introduction of Execution Context and Identity Models
The Source/Execution area now includes core domain models for managing runtime execution state. This introduces the ExecutionContext record, which aggregates microservice, tenant, version, environment, correlation, span, claims, and culture information, along with a custom ToString implementation. Supporting types include Claim and Claims for identity assertions, CorrelationId for traceability, and the ICreateExecutionContexts interface to facilitate context creation and validation. Additionally, the InvalidExecutionContext exception is provided to signal conflicts between requested and configured context values.
Source/Execution · high confidence
Metrics service now exposes .NET runtime stats via a dedicated Kestrel host
The metrics subsystem now includes a new hosted service that actively collects .NET runtime performance data using the Prometheus.DotNetRuntime library, exposing these metrics alongside standard application metrics. This capability is served by a dedicated Kestrel-based metrics host, which is configured to listen on a port defined in the application's configuration file. The implementation registers the necessary Prometheus collectors and DI bindings to ensure runtime statistics are available for monitoring.
Source/Metrics/Hosting · high confidence
MongoDB resource retrieval service implementation
Added the ResourcesService which implements the gRPC contract for retrieving MongoDB resources. This service accepts requests and delegates to the underlying MongoDB repository to fetch the specific resource for a given tenant, enabling the SDK to boot and access MongoDB configurations via the resources interface.
Source/Resources · high confidence
New General management pages for logs, metrics, and overview
The Management UI now includes dedicated pages under the General section. The Logs page provides a real-time view of system logs via gRPC streaming, displaying the most recent 20 entries with timestamps and messages, and includes a command bar with options to download logs (triggering a confirmation dialog) and sort or view in grid mode. The Overview page displays system health using line and doughnut charts. A placeholder Metrics page is also added to the navigation structure.
Source/ManagementUI/features/general · high confidence
New MongoDB utility extensions for async enumeration, telemetry, and upserts
The MongoDB integration now includes three new helper classes to simplify common operations. Users can convert async cursor sources into async enumerables via the new \AsyncCursorSourceExtensions\, enabling more idiative asynchronous iteration over MongoDB results. Telemetry capabilities are enhanced through \MongoClientSettingsExtensions\, which allows subscribing to MongoDB diagnostic events while automatically filtering out noisy internal commands like 'ping' and 'isMaster'. Additionally, \UpsertHelpers\ provides a convenient method to perform bulk upserts on MongoDB collections using a dictionary of entities.
Source/MongoDB · high confidence
New WebAPI service for committing and fetching events
The Event Store now exposes a dedicated WebAPI service (located at Source/Events.Store.Services.WebAPI) that allows clients to commit events and aggregate events, as well as fetch committed events for specific aggregate roots. This service introduces new HTTP endpoints under the /api/events route, including POST /commit for general event commits, POST /commitForAggregate for aggregate-specific commits, and POST /fetchForAggregate to retrieve historical events for an aggregate root instance. The implementation includes request and response models that handle the conversion between internal domain objects and the protobuf contracts used for communication.
Source/Events.Store.Services.WebAPI · high confidence
New async enumerable batching extensions for Protobuf messages
Added \BatchMessagesExtensions\ to the \Source/Rudimentary/AsyncEnumerators\ library, providing two new extension methods for \IAsyncEnumerable\<T\>\ where T is a Protobuf \IMessage\. The \CreateMessageBatchesOfSize\ method splits a stream of messages into batches based on a maximum byte size, while \BatchReduceMessagesOfSize\ aggregates messages within those size-limited batches using a provided reducer function. These utilities allow consumers to efficiently process large streams of Protobuf messages in size-constrained chunks.
Source/Rudimentary/AsyncEnumerators · high confidence
New attributes and extensions for DI lifecycle and scoping configuration
The DependencyInversion module now includes a new set of attributes and extension methods to declaratively configure dependency lifecycles and scoping. In the Lifecycle namespace, developers can use \[Singleton\] and \[Scoped\] attributes on classes, which are resolved via the new TypeExtensions.GetLifecycle() method to determine whether a type is instantiated once per application, once per unit of work, or transiently. Similarly, the Scoping namespace introduces the \[PerTenant\] attribute and Scopes enum, allowing types to be marked as shared globally or isolated per tenant via TypeExtensions.GetScope(). A new exception, TypeHasMultipleLifecycleAttributes, is thrown if a type incorrectly specifies multiple lifecycle attributes.
Source/DependencyInversion/Lifecycle, Source/DependencyInversion/Scoping · high confidence
New batched pipeline abstractions for item aggregation
The Source/Rudimentary/Pipelines area now includes a new set of interfaces and classes that enable building and managing batched item pipelines. This includes the IPipeline interface for adding items and retrieving ready batches, ICanAddToABatch and ICanBuildABatch for defining batch construction logic, and IPipelineReadyBatchAggregator for handling the aggregation and batching process. The implementation uses a channel-based approach to manage ready batches and provides mechanisms to complete or fail batches, allowing for more structured and efficient processing of items in batches.
Source/Rudimentary/Pipelines · high confidence
New bootstrap procedure execution framework
The system now includes a dedicated bootstrap module that manages the execution of initialization procedures. This introduces a \IBootstrapProcedures\ interface and a concrete implementation that iterates through registered \ICanPerformBoostrapProcedure\ instances in priority order, executing them globally and per-tenant. A new \HostExtensions\ method allows triggering this process during host startup, and a specific exception is thrown if bootstrap procedures are attempted to run more than once, ensuring idempotency.
Source/Bootstrap · high confidence
New configuration management service for retrieving system settings
A new Configuration Management service has been introduced, exposing a gRPC endpoint that allows users to retrieve the entire system configuration as a YAML string. The underlying implementation consolidates all application and tenant-specific configurations into a single, flattened structure, automatically removing empty objects and null values to ensure a clean output. This service is implemented via the \ConfigurationService\ class, which serializes the merged configuration state provided by the new \DolittleConfiguration\ singleton.
Source/Configuration.Management · high confidence
New configuration parsing capability via ConfigurationParser
A new \ConfigurationParser\ implementation and its \IParseConfigurationObjects\ interface have been added to the \Source/Configuration/Parsing\ location. This component enables the system to convert \IConfigurationSection\ data into strongly-typed \TOptions\ objects by serializing the configuration hierarchy into JSON and deserializing it using \Newtonsoft.Json\. This provides a standardized mechanism for parsing configuration sections into application options.
Source/Configuration/Parsing · high confidence
New dependency injection infrastructure with tenant-scoped service providers
This change introduces a new dependency inversion layer that replaces the previous setup with a structured, extensible DI system. It adds an assembly discovery utility (AssemblyFinder) to load dependencies based on filters and paths, and defines a set of interfaces (ICanAddServices, ICanAddTenantServices, IChildServiceProviderFactory) to allow modular service registration. The core implementation leverages Autofac to provide a global container and supports creating child service providers for specific tenants (TenantServiceProviders), enabling isolated, per-tenant service scopes while maintaining a shared global context.
Source/DependencyInversion · high confidence
New documentation assets and automation script
This change adds a new horizontal SVG logo asset (dolittle\_negativ\_horisontal\_RGB.svg) to the Documentation folder and introduces a new shell script (merge-compatibility-table-template.sh) designed to merge generated compatibility table data into a markdown template file, including logic to detect changes and set CI outputs.
Documentation · high confidence
New event filter processing infrastructure with validation and public filter support
The event processing system now includes a dedicated filter pipeline that validates filter definitions against persisted state before processing, ensuring consistency in partitioning and public status. This change introduces a new \AbstractFilterProcessor\ base class that handles event filtering logic, including graceful handling of already-written events by logging and skipping duplicates rather than failing. It also adds support for public filters via a new \PublicFilterProcessor\ and associated protocol definitions, allowing external clients to register and receive filtered events through a reverse-call dispatcher. The \FilterValidators\ component ensures that filter definitions are compatible with existing stream processors, preventing mismatches that could halt event processing.
Source/Events/Processing/Filters · high confidence
New event horizon consumer processing pipeline
The Event Horizon consumer now uses a dedicated processing pipeline in the Consumer/Processing module to handle incoming events. This includes an EventProcessor that commits external events to scoped event logs, an EventsFromEventHorizonFetcher that retrieves events via channels, and a StreamProcessor that manages subscription state and lifecycle. The implementation adds comprehensive metrics collection for processed events, fetches, and processor starts, along with retry policies for handling event store unavailability.
Source/EventHorizon/Consumer/Processing · high confidence
New gRPC hosting infrastructure with visibility-based service mapping and health checks
This change introduces the core hosting layer for gRPC services in the runtime. It adds a \HostBuilderExtensions\ that configures scoped Kestrel hosts for both gRPC and gRPC-web, automatically mapping discovered service implementations to endpoints based on their \EndpointVisibility\ (Public, Private, Management, ManagementWeb) via new \ServiceAttribute\ markers. It also integrates a \HealthService\ that always reports healthy and an \EndpointHealthCheck\ that actively probes specific endpoint ports to verify connectivity, ensuring operational visibility for the newly exposed gRPC interfaces.
Source/Services/Hosting · high confidence
New metric collection service registration
The Metrics/DependencyInversion area now includes a new MetricCollector class and a Services implementation that registers metric collectors as singletons in the dependency injection container. This enables automatic registration of types marked with MetricsAttribute, allowing the system to collect metrics for specific collector types through the dependency injection framework.
Source/Metrics/DependencyInversion · high confidence
New metrics infrastructure and logging support
The metrics subsystem now includes a dedicated logging class for structured log messages (such as server startup details) and a custom attribute to mark classes that provide metrics. Additionally, extension methods have been added to the Prometheus metric factory to simplify the creation of counters, gauges, and histograms with custom labels and buckets.
Source/Metrics · high confidence
New reverse call service infrastructure with request identification and validation
The Services layer now includes a complete foundation for reverse call communication, introducing interfaces for dispatching calls (IReverseCallDispatcher), initiating connections (IInitiateReverseCallServices), and converting messages (IConvertReverseCallMessages). This change adds specific validation for connect arguments, throwing ConnectArgumentsValidationFailed or ConnectArgumentsNotReceived when invalid, and introduces a HeaderRequestIdentifier to assign unique RequestIds to service requests via the 'x-request-id' header. Additionally, it defines EndpointVisibility to categorize endpoints (Public, Private, Management, ManagementWeb) and implements a MetricsCollector to track reverse call request counts and durations.
Source/Services · high confidence
New rudimentary utility types and extensions for error handling and concurrency
The Source/Rudimentary library now includes several new foundational types to improve code safety and concurrency management. The Try and Try\<TResult\> monads provide a structured way to handle operation results and exceptions, featuring chaining methods like Then, Catch, Select, and Reduce for both synchronous and asynchronous workflows. A new Partial type extends Try to support partial success scenarios where a result is available alongside an exception. Additionally, a TaskGroup class allows grouping multiple tasks that cancel each other when the first one completes, while helper extensions for Exception and Task simplify retrieving innermost exceptions and handling task failures.
Source/Rudimentary · high confidence
New runtime management commands for aggregates, configuration, and event processing
The CLI now includes a new 'dolittle runtime' command group that allows users to inspect and manage runtime components. This adds the 'runtime aggregates get' command to retrieve aggregate root instances (supporting both simple and detailed views, with output in table or JSON format), the 'runtime config' command to fetch the runtime's configuration as YAML, and the underlying infrastructure to discover available runtimes (including Docker-based ones) and create gRPC management clients. It also introduces services to convert and display stream processor statuses, enabling users to monitor event processing health.
Source/CLI/Runtime · high confidence
New stream processor infrastructure with metrics and retry logic
This change introduces the core stream processing components in the \Source/Events/Processing/Streams\ directory, including the \AbstractScopedStreamProcessor\ base class and its \ScopedStreamProcessor\ implementation for unpartitioned streams. It adds a factory (\CreateScopedStreamProcessors\) to manage processor lifecycle and state, along with retry policies (\EventFetcherPolicies\) that implement exponential backoff for event store unavailability. The update also integrates OpenTelemetry and Prometheus metrics collection (\MetricsCollector\) to track registration, processing, and failure rates per event processor kind, and defines specific exception types for stream processor state management.
Source/Events/Processing/Streams · high confidence
New type-scanning and grouping utilities for dependency injection
The DependencyInversion module now includes a new set of types in the Source/DependencyInversion/Types directory to support automatic service discovery and registration. This adds a TypeScanner that identifies classes within Runtime assemblies and groups them by DI scope (Global vs. Per-Tenant) and lifecycle (Singleton, Scoped, Transient). It also introduces helper extensions for filtering types by attributes or interface implementation, and specific logic to extract generic type arguments from implemented interfaces, along with corresponding validation exceptions.
Source/DependencyInversion/Types · high confidence
OpenTelemetry integration for runtime diagnostics
The Diagnostics project now includes native OpenTelemetry support, allowing the runtime to export logs, traces, and metrics to an OTLP endpoint. This change introduces configuration for the OTLP endpoint, service name, and toggles for logging, tracing, and metrics. It wires up instrumentation for ASP.NET Core, HTTP clients, gRPC clients, ProtoActor, and MongoDB, while also defining a custom ActivitySource and Meter for runtime-specific telemetry.
Source/Diagnostics · high confidence
Support for per-tenant dependency resolution via tenant-specific factories
The dependency injection container now supports resolving services on a per-tenant basis using factory delegates (e.g., \Func\<TenantId, TResult\>\). A new \GeneratedTenantFactoryRegistrationSource\ automatically registers these factories, allowing code to request a service instance specific to a given tenant ID. If resolution fails for a specific tenant, a new \FailedToResolveServiceForTenant\ exception is thrown to provide clearer error context. This is enabled via the new \AddTenantFactories\ extension method on the container builder.
Source/DependencyInversion/Tenancy · high confidence
Behavioural changes
Add configuration models for event horizon consent and subscriptions
Introduced new configuration classes in the Event Horizon module to define how consent and subscriptions are structured. ConsentConfiguration now explicitly defines the partition as a string rather than a Guid, aligning the data model with the actual stream partitioning requirements. Additionally, new classes (EventHorizonConfiguration, EventHorizonsPerMicroserviceConfiguration, SubscriptionConfiguration, and SubscriptionsPerProducerConfiguration) provide the structured schema for mapping tenant-specific event horizon settings, including per-producer subscription scopes and consent details.
Source/EventHorizon/Configuration · high confidence
Background migration to V9 with V6 event source ID conversion
The MongoDB event store now runs database migrations in the background, allowing the runtime to continue processing events without blocking. This update introduces migration V9, which specifically converts V6 event source IDs from GUID format to strings, eliminating the need for a V6 compatibility mode. The migration also cleans up default metadata for Event Horizon and Aggregate fields where they are not applicable, and tracks migration status in a new database metadata collection.
Source/Events.Store.MongoDB/Migrations · high confidence
Backward-compatible protobuf serialization for partition and event source identifiers
The Event Horizon now supports legacy partition IDs and event source IDs in its protobuf contracts, allowing consumers using older client versions to continue functioning without breaking changes. New extension methods in ProtobufExtensions handle the conversion between internal domain models and protobuf messages by checking for the presence of new identifier fields and falling back to legacy GUID-based fields when necessary, ensuring smooth interoperability during the transition period.
Source/EventHorizon/UnBreaking · high confidence
CLI now supports parsing event handlers by ID or alias with optional scope
The CLI now accepts event handler identifiers in a more flexible format. Users can specify an event handler by its unique ID (GUID) or by a human-readable alias. Additionally, the parser supports an optional scope identifier, allowing users to disambiguate handlers across different scopes by providing the format 'ID:ScopeId' or 'Alias:ScopeId'. This change introduces a new parser (\EventHandlerIdOrAliasParser\) and a specific validation exception (\InvalidEventHandlerIdOrAlias\) to handle these inputs and provide clear error messages when the format is incorrect.
Source/CLI/Options/Parsers/EventHandlers · high confidence
Centralized registration of CLI option parsers
The CLI now uses a centralized dependency injection setup to register all command-line option parsers. A new \ServiceCollectionExtensions\ class explicitly registers specific parsers for microservice addresses, versions, event processor/tenant/scope IDs, event sources, stream positions, and event handler or aggregate root identifiers. A corresponding \ValueParserProviderExtensions\ method allows the application to automatically discover and register all these parsers from the service container, ensuring consistent parsing behavior across commands.
Source/CLI/Options/Parsers · high confidence
Configurable MongoDB backwards compatibility for legacy Event Store schemas
The MongoDB Event Store now supports configurable backwards compatibility, allowing it to read data persisted by previous runtime versions (v6 and v7) where EventSource and Partition identifiers were stored as GUIDs rather than strings. This change introduces a new \BackwardsCompatibility\ component in the \Source/Events.Store.MongoDB/Legacy\ area that registers custom MongoDB serializers and query filters. These components transparently handle fields that may contain either a string or a binary GUID, ensuring that queries and deserialization work correctly regardless of the original storage format, while eliminating the need for a dedicated V6 compatibility mode.
Source/Events.Store.MongoDB/Legacy · high confidence
Configurable gRPC service endpoints and reverse calls
The system now allows management of gRPC service endpoints and reverse call behavior through configuration. Users can enable or disable specific endpoints (Public, Private, Management, ManagementWeb) and define their ports via the new EndpointConfiguration model. Additionally, the system supports configuring whether actors are used for reverse calls through the ReverseCallsConfiguration settings.
Source/Services/Configuration · high confidence
Corrected legacy stream position mapping to event log sequence
The legacy stream processing component now correctly maps stream positions to event log sequences, ensuring that the proper offset is retrieved from the V8 stream source. This change replaces the previous implementation with a new service that handles both partitioned and non-partitioned stream states, including logic to fetch the last event when at the end of a stream or start from the beginning if no events exist, thereby fixing potential state synchronization issues in legacy event processing.
Source/Events/Store/Streams/Legacy · high confidence
Event Horizon producer-side subscription and event streaming implementation
The Event Horizon producer now handles incoming consumer subscriptions via a new gRPC-based reverse call mechanism. The \ConsumerService\ validates tenant existence and consent requirements before accepting a subscription, while the \EventHorizon\ class manages the active stream by fetching events from the event store and dispatching them to the consumer. This change introduces specific failure handling for scenarios such as missing producer tenants, duplicate registrations, and unavailable event stores, and adds comprehensive metrics collection to track incoming, accepted, and rejected subscriptions as well as events written to the horizon.
Source/EventHorizon/Producer · high confidence
Event handlers now support graceful shutdown and configurable processing windows
The event processing system has been updated to allow event handlers to gracefully disconnect from the client and to define specific processing boundaries. Clients can now register event handlers with a start position (earliest, latest, or a specific timestamp) and an optional stop timestamp, enabling handlers to process events only within a defined time window. Additionally, the protocol now supports graceful shutdown signals, ensuring that active event handlers are properly terminated when the runtime or client disconnects, improving system stability and resource management.
Source/Events/Processing/EventHandlers · high confidence
Event processors now return structured processing results
The event processing pipeline has been updated so that the IEventProcessor interface returns a ProcessingResult (IProcessingResult) instead of void or simple success/failure. This allows processors to explicitly signal success, failure with a reason, or skipped events, and to request retries with specific timeouts. New result types (SuccessfulProcessing, FailedProcessing, SkippedProcessing) and supporting types (EventProcessorKind, EventProcessorRegistrationResult, EventLogSequenceAlreadyWritten) provide clearer feedback on processing outcomes and registration status.
Source/Events/Processing · high confidence
Event store actors rewritten with new state management and subscription handling
The event store actors have been completely rewritten to improve memory efficiency and reliability. The new architecture introduces a dedicated \EventLogStream\ actor for managing subscriptions with bounded channels to prevent unbounded memory usage, and a \Committer\ actor that handles event persistence with improved batching and aggregate root version caching. State management for stream processors and subscriptions is now handled by \StreamProcessorStateManager\, which persists state to a repository and supports both partitioned and non-partitioned processing. The \Bucket\ class now maps directly to \IStreamProcessorState\, and catch-up processing is handled by \EventStoreCatchupActor\ with configurable batch sizes. Metrics collection has been expanded to track commit counts, persistence success/failure, aggregate root version inconsistencies, and subscription event streaming vs. catch-up events, exposed via both Prometheus and OpenTelemetry.
Source/Events/Store/Actors · high confidence
Introduce configurable metrics server endpoint settings
Added a new configuration record for the metrics server that allows users to control whether the endpoint is enabled and specify the port it listens on (defaulting to 9700). This replaces hardcoded values with a structured configuration approach, enabling easier customization of the metrics service behavior.
Source/Metrics/Configuration · high confidence
Introduce dependency-inversion-based configuration with tenant support
The configuration system now uses the Options pattern integrated with the dependency-inversion container. Configuration objects are registered via attributes (ConfigurationAttribute and TenantConfigurationAttribute), and a custom OptionsFactory parses configuration sections (prefixed with dolittle:runtime:) into strongly-typed options. Tenant-specific configurations are supported by resolving them from a tenants-scoped section (tenants:{tenantId}:{section}) via TenantOptionsFactory, while non-tenant configurations are resolved from the root container. Attempting to resolve a tenant-specific configuration from the root container now throws CannotCreateTenantSpecificConfigurationFromRootContainer, and parsing failures throw CannotParseConfiguration with details about the type and section.
Source/Configuration/DependencyInversion · high confidence
Introduce reverse call client protocol and Grpc.Net.Client migration
Services.Clients now implements a new reverse call protocol for duplex streaming, introducing interfaces like IReverseCallClient, IReverseCallClients, and IReverseCallClientProtocol to manage server-to-client connections. The implementation migrates from the legacy Grpc.Core library to Grpc.Net.Client, utilizing a new Channels abstraction for channel creation. Additionally, the module adds comprehensive metrics collection for reverse calls (tracking connections, writes, pings, and timeouts) via both Prometheus and OpenTelemetry, and standardizes logging using ILoggerMessage extensions.
Source/Services.Clients · high confidence
Introduces graceful shutdown and cluster hosting infrastructure for Proto.Actor
The Actors Hosting layer now provides a structured lifecycle for the Proto.Actor system, ensuring that stream processors and event handlers complete their work before the service terminates. This is achieved through new \IApplicationLifecycleHooks\ and \IStreamProcessorLifecycleHooks\ interfaces that coordinate a graceful shutdown sequence, preventing data loss during restarts. The \ActorSystemClusterHostedService\ orchestrates this process, while \HostBuilderExtensions\ configures the actor system with a \SingleNodeProvider\ for single-server deployments and integrates OpenTelemetry tracing. Additionally, cluster kinds are automatically discovered via \ClusterConfigExtensions\, which applies request deduplication to grains, and a logger proxy is used to reduce noise from Proto.Actor internals.
Source/Actors/Hosting · high confidence
Introduction of public event stream filtering capabilities
The event store now supports filtering events into public streams, allowing events to be written to streams accessible outside the current scope. This change introduces new interfaces and definitions, including \IWriteEventsToPublicStreams\ and \PublicFilterDefinition\, which distinguish public filters from standard remote filters. Public filters are marked with a \Public\ property and are excluded from validation checks that previously caused delays in starting event horizon producers, thereby improving startup performance for systems utilizing public event streams.
Source/Events/Store/Streams/Filters · high confidence
MongoDB aggregate root versioning and concurrency control
The MongoDB event store now manages aggregate root state and versions directly, introducing optimistic concurrency control to prevent data corruption. A new \aggregates\ collection stores the \EventSource\, \AggregateType\, and a \ulong\ version for each root, protected by a unique composite index. The \AggregateRoots\ service handles version increments by checking the expected version before writing, throwing \AggregateRootConcurrencyConflict\ if a race condition is detected, and ensuring the next version is always greater than the current one. An \AggregateRootInstancesFetcher\ allows retrieving these instances by aggregate type.
Source/Events.Store.MongoDB/Aggregates · high confidence
MongoDB event store model and conversion layer refactored for new runtime interface
The MongoDB event store's internal data models and conversion logic have been rewritten to align with a new runtime interface. This introduces dedicated store-specific types (Event, StreamEvent, ExecutionContext, Claim, Version) and a new IEventConverter that handles serialization between MongoDB's BSON format and the runtime's CommittedEvent representations. Key behavioral changes include using ulong for sequence numbers and versions, storing DateTime values as UTC, and separating aggregate and event horizon metadata into distinct structures to support sparse event streams and partitioned event logs.
Source/Events.Store.MongoDB/Events · high confidence
MongoDB event store now supports writing to event horizons and public streams
The MongoDB event store implementation has been extended to handle event horizon and public stream writes. This change introduces the EventHorizonEventsWriter and EventsToPublicStreamsWriter components, which enable the store to commit events to specific event logs and public streams respectively. These writers utilize the new IEventConverter to translate between runtime and store representations and notify stream watchers upon successful writes, ensuring that legacy stream processors and scoped subscriptions receive updates correctly.
Source/Events.Store.MongoDB/EventHorizon · high confidence
MongoDB event store persistence layer refactored with GDPR redaction and offset management
The MongoDB persistence implementation for event streams has been rewritten to introduce several key capabilities. First, it now supports GDPR redaction, allowing specific personal data fields within stored events to be updated or unset in bulk via the new RedactionUtil. Second, offset tracking for event logs is now managed explicitly through a dedicated OffsetStore, which initializes and corrects stream offsets on startup to ensure consistency. Third, aggregate root versions are now updated automatically after each commit via the UpdateAggregateVersionsAfterCommit component, ensuring version state is persisted alongside events. Finally, the commit writing process has been streamlined with a new ConvertCommitToEvents converter and a unified CommitWriter that handles transactional storage, redaction, and offset updates in a single MongoDB session.
Source/Events.Store.MongoDB/Persistence · high confidence
MongoDB event store refactored for sparse logs and batched fetching
The MongoDB event store implementation has been rewritten to support sparse event logs, allowing the system to continue operating even when old events have been truncated or scavenged. The new \CommittedEventsFetcher\ introduces batched fetching for aggregate events and optimized stream processing to reduce memory usage. Configuration has been unified to support both modern connection strings and legacy server lists, with an adjustable \MaxConnectionPoolSize\. Additionally, the store now uses projections to avoid loading unnecessary event horizon metadata and includes custom discriminator registration for improved serialization.
Source/Events.Store.MongoDB · high confidence
MongoDB event store stream handling rewritten for partitioned streams and sparse logs
The MongoDB event store's stream handling has been completely rewritten to support partitioned event streams and sparse event logs. This change introduces new components in the \Source/Events.Store.MongoDB/Streams\ directory, including \EventFetchers\ and \StreamFetcher\, which now use LINQ expressions to efficiently fetch events from both public and scoped stream collections, as well as the event log. The \EventsToStreamsWriter\ has been updated to handle write conflicts and duplicate key errors more robustly, ensuring data integrity when appending events. Additionally, the \Streams\ class now manages collection and index creation for event logs and stream definitions, optimizing queries for aggregate versions and event sources. These changes enable the runtime to operate correctly with truncated or scavenged old events and improve performance through partitioned processing.
Source/Events.Store.MongoDB/Streams · high confidence
MongoDB filter persistence and deserialization reworked
The MongoDB storage layer for stream filters has been rewritten to use a new abstract base class, AbstractFilterDefinition, and a custom discriminator convention. This change introduces specific persisted types (RemoteFilterDefinition and TypePartitionFilterDefinition) to handle filter serialization, ensuring that filter definitions are correctly round-tripped between the runtime and the database. It also adds robust error handling for missing or unsupported filter types during deserialization.
Source/Events.Store.MongoDB/Streams/Filters · high confidence
MongoDB partitioned stream processor state persistence updated
The MongoDB storage layer for partitioned stream processors now persists additional failure tracking metadata. Specifically, the \FailingPartitionState\ model includes a new \LastFailed\ timestamp to record when a partition last failed, and the \PartitionedStreamProcessorState\ now tracks the \LastSuccessfullyProcessed\ timestamp at the processor level. These changes ensure that failure history and last-successful processing times are correctly stored and mapped to the runtime representation.
Source/Events.Store.MongoDB/Processing/Streams/Partitioned · high confidence
MongoDB stream processor state persistence rewritten
The MongoDB event store's stream processor state management has been completely rewritten to use a new, dedicated persistence layer. This change introduces a new \AbstractStreamProcessorState\ model and a custom \StreamProcessorStateDiscriminatorConvention\ to handle serialization of both standard and partitioned stream states. The new \StreamProcessorStateRepository\ and \SubscriptionStateRepository\ implementations replace previous logic, introducing scoped collection handling (prefixing collections with \x-{scope}\), unique compound indexes on \EventProcessor\ and \SourceStream\, and explicit UTC datetime handling. Users will see improved reliability in state persistence, better support for partitioned streams, and clearer error handling for scope mismatches or unsupported state types.
Source/Events.Store.MongoDB/Processing/Streams · high confidence
MongoDB subscription state model and storage layer updated
The MongoDB event store's subscription state handling has been refactored to include a new \SubscriptionState\ document model that explicitly tracks \EventLogSequence\ alongside the stream position, and enforces UTC time zones for \LastSuccessfullyProcessed\ and \RetryTime\ fields. This change introduces a new scoped collection structure (\x-{scope}-subscription-states\) with unique composite indexes on Microservice, Tenant, Stream, and Partition, and provides extension methods to map this storage representation to the runtime's \StreamProcessorState\.
Source/Events.Store.MongoDB/Processing/Streams/EventHorizon · high confidence
New Autofac-based dependency injection container with automatic service discovery and logging support
The application now uses a custom Autofac-based service provider factory to manage dependencies, replacing the previous default implementation. This change introduces automatic service discovery via reflection, allowing types implementing specific interfaces (such as ICanAddServices) to register themselves without manual configuration. It also adds built-in support for Microsoft.Extensions.Logging, automatically injecting ILogger instances into constructors that require them, and provides a new exception type (CouldNotCreateInstanceOfType) to handle instantiation failures gracefully.
Source/DependencyInversion/Building · high confidence
New actor-based event handler processing with partitioned concurrency
The event handler processing logic has been rewritten to use an actor-based architecture (Proto), introducing \ActorEventHandler\ and \EventHandlerProcessorActor\ to manage the lifecycle and tenant-scoped stream processors. This change adds support for concurrent, partitioned event processing via \ConcurrentPartitionedProcessor\, allowing handlers to process events in parallel based on \eventsourceId\. The new implementation includes specific processors for partitioned (\PartitionedProcessor\) and non-partitioned (\NonPartitionedProcessor\) streams, with a base \ProcessorBase\ handling common retry and state persistence logic. Users benefit from improved resilience, lower memory footprint during retries (reading from DB instead of keeping in memory), and the ability to start processing from a specific timestamp or offset.
Source/Events/Processing/EventHandlers/Actors · high confidence
New server entry point and default configuration
The runtime now uses a new \Program.cs\ entry point that consolidates configuration loading (JSON, environment variables, command line) and service registration, including OpenTelemetry, metrics, and multiple gRPC hosts (Public, Private, Management). A new \appsettings.json\ provides default port assignments (Public: 5052, Private: 5053, Management: 5152, ManagementWeb: 5153) and sets default logging levels to Information, with specific warnings for Proto, Microsoft.AspNetCore, and Grpc.AspNetCore namespaces. The startup process now explicitly validates that tenants are configured, logging a warning or error if none are found.
Source/Server · high confidence
Optional event horizon consent enforcement
The Event Horizon module now supports a global configuration setting that allows administrators to disable the requirement for producer consent when consuming events. A new \EventHorizonGlobalSettings\ class introduces a \RequireConsent\ property (defaulting to true) under the \eventHorizon\ configuration section, enabling users to opt out of the consent mechanism if desired.
Source/EventHorizon · high confidence
Partitioned stream processors now track and retry failing partitions independently
The partitioned stream processor implementation has been rewritten to support granular failure handling per partition. Instead of failing the entire stream processor when a single partition encounters an error, the system now tracks the state of each failing partition separately (including retry times and failure reasons) via the new \FailingPartitionState\ and \FailingPartitions\ components. This allows the processor to continue processing other partitions while retrying failed ones according to their specific schedules, and to catch up on failed partitions when they become ready, improving overall resilience and throughput for partitioned event streams.
Source/Events/Processing/Streams/Partitioned · high confidence
Platform context execution and configuration restructured
The Platform module now introduces a dedicated ExecutionContextCreator to handle the creation and validation of execution contexts, ensuring that tenant, microservice, and environment details align with the configured PlatformConfiguration. This configuration class has been expanded to explicitly include CustomerId, CustomerName, ApplicationId, ApplicationName, and MicroserviceId properties, moving away from previous ConceptAs type patterns to provide clearer identity management for runtime contexts. Additionally, the VersionInfo class has been updated to reflect the current runtime version (377.389.368.0) with a PRERELEASE tag, and warnings for empty strings in prerelease builds have been suppressed.
Source/Platform · high confidence
Projections feature disabled with client version enforcement
The Projections capability in the Runtime is now disabled; any attempt to connect triggers an UnsupportedClientVersion exception and logs a message instructing users to migrate to SDK version 23 or newer. This change is implemented via the new ProjectionsService, which intercepts connection attempts and rejects them, alongside supporting types like UnsupportedClientVersion and logging extensions.
Source/Events/Processing/Projections · high confidence
Redesigned stream processing state and subscription model
The event store's stream processing architecture has been rewritten to introduce a dedicated \ProcessingPosition\ that tracks both stream and event log positions, allowing processors to update the event log position even when skipping events. A new \IStreamEventSubscriber\ interface and \StreamSubscriptionMessage\ struct replace the previous watch functionality, enabling subscriptions to specific event types and providing the next event log sequence number when no matching events are found. Stream processor state is now managed via a new \IStreamProcessorState\ interface that explicitly tracks failing partitions and earliest processing positions, while new interfaces like \IEventFetchers\ and \IStreamDefinitionRepository\ standardize how events are fetched and stream definitions are persisted.
Source/Events/Store/Streams · high confidence
Refactored health check endpoint with tenant-aware checks and standardized response
The health check system has been restructured to improve clarity and Kubernetes compatibility. The endpoint response is now formatted using the Microsoft JSON serializer with indented output and null-value suppression, ensuring a consistent and readable status report. Health checks are now automatically registered based on their implementation types, removing the need for manual configuration. Additionally, the checks have been split into specific implementations (such as Event Store and MongoDB resource checks) that aggregate results across all tenants, providing detailed per-tenant health status in the response.
Source/Server/HealthChecks · high confidence
Refactored reverse call handling into dedicated dispatcher and stream writer actors
The reverse call mechanism has been split into two distinct actors: a \ReverseCallDispatcherActor\ that manages connection lifecycle, request/response routing, and graceful disconnects, and a \ReverseCallStreamWriterActor\ that handles the actual message streaming and ping logic. This separation allows for cleaner logging, better support for graceful shutdowns via dedicated tokens, and more robust handling of stream writes with ping timeouts and metrics collection.
Source/Services/Actors · high confidence
Resilient Event Horizon subscription with metrics and retry logic
The Event Horizon Consumer now manages subscriptions with built-in resilience and observability. Subscriptions automatically retry connections to the producer runtime using an exponential backoff policy (up to 60 seconds) if the connection fails, ensuring continuous operation without manual intervention. The system now exposes detailed metrics for monitoring subscription health, including counts of total requests, active connections, and various failure modes (such as missing microservice configuration or connection errors), available via both Prometheus and OpenTelemetry. Additionally, the subscription lifecycle is more transparent, with clear state tracking (Created, Connecting, Connected) and structured logging for debugging connection and processing issues.
Source/EventHorizon/Consumer · high confidence
Runtime handshake now validates SDK contract compatibility and returns specific upgrade guidance
The Platform handshake service now checks whether the Client SDK's Contracts version is compatible with the Runtime. If the SDK is too old, the handshake fails with a clear message instructing the user to upgrade the SDK; if the Runtime is too old, it fails with a message instructing the user to upgrade the Runtime. This prevents silent mismatches and ensures clients receive actionable feedback during connection.
Source/Platform/Handshake · high confidence
Stream processor now prevents re-initialization
The Stream Processor now enforces that it can only be initialized once. Attempting to call Initialize() a second time will fail with a StreamProcessorAlreadyInitialized exception, ensuring that the processor's state is not accidentally reset or duplicated during its lifecycle.
_Specifications/Events.Processing/Streams/for\_StreamProcessor/when\initializing · high confidence
Unified MongoDB connection string configuration with backward compatibility
The MongoDB resource configuration now supports a unified connection string approach while remaining backward compatible with the previous host-based format. Users can now provide a full MongoDB connection string via the new ConnectionString property, which takes precedence if present; otherwise, the system falls back to constructing the connection from the existing Host, Database, and UseSSL settings. This change simplifies configuration by allowing standard MongoDB URI formats and ensures that existing deployments using the older host-based configuration continue to work without modification.
Source/Resources/MongoDB · high confidence
Unified runtime configuration with legacy file support
The system now loads configuration from a single \runtime.json\ file located in the \.dolittle\ directory, while maintaining backward compatibility by merging in settings from legacy individual files (such as \endpoints.json\, \platform.json\, \microservices.json\, \resources.json\, and \event-horizon-consents.json\) found in the same directory. This change introduces a new \RuntimeFileConfigurationProvider\ that maps these legacy structures into the unified \dolittle:runtime\ configuration path, ensuring that both global and per-tenant configuration objects are populated correctly from the combined source.
Source/Configuration · high confidence
Upgraded development container to .NET 9 with multi-architecture support and integrated MongoDB
The development Docker image has been upgraded from .NET 7/8 to .NET 9, enabling multi-architecture builds (including ARM64) and using Debian-based runtime images. The container now bundles MongoDB 7.0, automatically initializing a replica set and starting both the database and the .NET runtime via a new entrypoint script that ensures ordered startup and graceful shutdown.
Docker/Development · high confidence
gRPC Event Store service now delegates to IEventStore
The gRPC service implementation has been refactored to act as a thin wrapper around the IEventStore interface, replacing previous direct logic with calls to CommitEvents, CommitAggregateEvents, and FetchAggregateEvents. This change centralizes event store operations within the IEventStore abstraction, ensuring the gRPC layer strictly handles protocol translation and batching (such as FetchForAggregateInBatches) while delegating core persistence and retrieval logic to the underlying service.
Source/Events.Store.Services.Grpc · high confidence
Test coverage
Add specifications for CallbackScheduler behavior; Add test fixture for CommittedAggregateEvent construction; Add test fixture for EmbeddingProcessor deletion scenario; Add test fixture for embedding projection context; Added Protobuf serialization tests for execution context and claims; Added actor-level specifications for the Reverse Call Dispatcher; Added benchmarks for event handler and filter processing performance; Added benchmarks for stream processor state persistence and retrieval; Added event store commit and fetch benchmarks; Added execution context factory for event store specifications; Added in-memory test infrastructure for event processing specifications; Added integration test infrastructure for event handlers; Added integration test infrastructure for event processing; Added integration tests for MongoDB StreamProcessorStateRepository; Added integration tests for Services reverse call functionality; Added integration tests for StreamProcessorId state storage; Added integration tests for event stream writing scenarios; Added integration tests for gRPC event store service; Added integration tests for partitioned event handler state management; Added integration tests for scoped event handlers; Added integration tests for scoped partitioned event handlers; Added integration tests for scoped, unpartitioned event handlers; Added integration tests for stream processor state retrieval by subscription ID; Added integration tests for the Events Store; Added integration tests for the event store commit workflow; Added integration tests for unpartitioned event handlers without implicit filtering; Added shared test fixture for subscription specifications; Added specification for EventProcessor event processing; Added specification for StreamPositionRange creation; Added specification for public event filter success scenario; Added specification for scoped stream processor event handling; Added specification test fixtures for primitive concepts; Added specification tests for ConceptAs equality, hashing, and value retrieval; Added specification tests for Embedding comparison behavior; Added specification tests for EmbeddingRequestFactory request creation; Added specification tests for EmbeddingStoreGrpcService retrieval operations; Added specification tests for EmbeddingsService retrieval methods; Added specification tests for EventProcessor creation; Added specification tests for ProjectManyEvents projection logic; Added specification tests for ReverseCallDispatcher acceptance scenarios; Added specification tests for embedding delete request creation; Added specification tests for embedding projection error handling; Added specification tests for embedding projection response handling; Added specification tests for embedding request factory projection handling; Added specification tests for filter validation edge cases; Added specification tests for multi-tenant embedding processor startup; Added specification tests for subscription lifecycle states; Added specification tests for the ReverseCallDispatcher; Added specifications for AbstractFilterProcessor event handling scenarios; Added specifications for AggregateRoots and AggregateRootInstances behavior; Added specifications for CommittedAggregateEvents extension; Added specifications for CommittedAggregateEvents validation and behavior; Added specifications for EmbeddingProcessor startup behavior; Added specifications for EmbeddingStateUpdater failure and multi-key scenarios; Added specifications for EmbeddingStore replace and remove operations; Added specifications for EmbeddingStore state retrieval and key filtering; Added specifications for EmbeddingStore state retrieval scenarios; Added specifications for EmbeddingsService connection behavior; Added specifications for EmbeddingsService delete and update operations; Added specifications for Event Horizon connection scenarios; Added specifications for Event Horizon subscription connection resilience; Added specifications for EventHandler disposal and registration failure scenarios; Added specifications for EventHorizon Protobuf extension conversions; Added specifications for EventHorizon connection event reception and cancellation; Added specifications for EventProcessor creation and event processing; Added specifications for MongoDB event store metadata and conversion logic; Added specifications for PingedConnection and ReverseCallStreamWriter; Added specifications for RemoteFilterDefinition and TypePartitionFilterDefinition; Added specifications for ReverseCallClient connection and handling scenarios; Added specifications for ReverseCallClient connection handling scenarios; Added specifications for ReverseCallDispatcher argument reception; Added specifications for ReverseCallDispatcher call handling; Added specifications for StateTransitionEventsCalculator convergence scenarios; Added specifications for StreamEventWatcher notification behavior; Added specifications for StreamProcessorState construction; Added specifications for TypeFilterWithEventSourcePartition filtering behavior; Added specifications for UncommittedAggregateEvents and UncommittedEvents; Added specifications for Version and Claims equality; Added specifications for comparing filter definitions; Added specifications for embedding definition comparison across tenants; Added specifications for embedding definition persistence across tenants; Added specifications for embedding deletion failure scenarios; Added specifications for embedding deletion state transitions; Added specifications for failing partition retry behavior; Added specifications for failing partition retry logic during catch-up; Added specifications for multi-partition retry behavior during catch-up; Added specifications for multi-tenant embedding processor lifecycle; Added specifications for partitioned event stream catch-up retry logic; Added specifications for partitioned stream processor state and failure handling; Added specifications for platform contracts compatibility verification; Added specifications for scoped stream processor failure and retry behavior; Added specifications for scoped stream processor failure and retry handling; Added specifications for scoped stream processor partition failure handling; Added specifications for scoped stream processor position setting; Added specifications for service request identifier logic; Added specifications for stream definition creation behavior; Added specifications for subscription event retrieval logic; Added specifications for the Embedding Loop Detector; Added specifications for unpartitioned stream processor retry timing; Added test artifacts and execution context helpers for Event Horizon specifications; Added test fixture for CommittedEvent specifications; Added test fixture for Embedding deletion scenarios; Added test fixture for Embedding processing specifications; Added test fixture for EmbeddingProcessor update scenarios; Added test fixture for multiple failing partitions during catch-up; Added test fixtures for Subscription specifications; Added test fixtures for failing partition event processing; Added test for cancelling one callback while others continue; Added test for catching up when no partitions are failing; Added test for event claims handling in event horizon conversion; Added test for subscription behavior when connection fails after starting; Added test harness for partitioned scoped stream processor specifications; Added test helper for single-tenant event handler scenarios; Added test helpers for partitioned event handler scenarios; Added test infrastructure for EmbeddingStoreGrpcService specifications; Added test infrastructure for unpartitioned event handlers; Added test scaffolding for EmbeddingProcessors with multi-tenant support; Added test scaffolding for EmbeddingStateUpdater specifications; Added test scaffolding for GetNextEventToReceiveForSubscription specification; Added test scaffolding for TypeFilter with EventSourcePartition; Added test scaffolding for embedding definition comparison; Added test scaffolding for embedding definition persistence; Added test specifications and helpers for MongoDB Event Store; Added test specifications and mocks for EmbeddingsService; Added tests for AsyncCursorSourceExtensions iteration behavior; Added tests for MongoDB event store offset handling and stream ID matching; Added tests for StreamProcessorState serialization mappings; Added tests for UpdateAggregateVersionsAfterCommit in MongoDB persistence; Added tests for embedding definition conversion; Added tests for partitioned stream processor retry timing logic; Added tests for projection state comparison logic; Added tests for stream processor registration logic; Added tests for stream processor state management and concurrent partitioned processing; Added unit tests for event store model constructors; Added unit tests for stream filter definitions; Established shared test fixtures for EmbeddingProcessor specifications; Establishes shared test fixtures for EmbeddingStore specifications; Establishes test fixture for ScopedStreamProcessor specifications; Initial specification scaffolding for Actor-based Event Handler processing; New integration test infrastructure for the Event Store; Refactored StreamEventWatcher test infrastructure; Refactored test fixture dependencies for StreamProcessor specs; Scoped stream processor behavior when setting position; Updated test fixture for EventHorizon connection event reception; Updated test fixture for failing partition catching-up scenario; Updated test fixture for failing partition catching-up scenarios.
Dependencies
Migrated to central package management
The project has adopted central package management via a new Directory.Packages.props file, which now defines the versions for all NuGet packages used across the solution. This change simplifies dependency upgrades and ensures version consistency by allowing individual .csproj files to reference packages by name only, without specifying versions. The manifest includes versions for key libraries such as Dolittle.Contracts (7.8.1), Autofac (8.1.1), Grpc.AspNetCore (2.71.0), MongoDB.Driver (2.30.0), and Microsoft.Extensions.\* (9.0.8).
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 39.
Lenses
- Code Health 43
- Architecture 95
- Maturity 63
- Readiness 39
- Security 33
- Accessibility 37
- Performance 68
Changes since last survey
- 300 commits — 281 feature/other, 19 fixes
By area
- (root) — 51 commits
- Source/Events — 49 commits
- (repo) — 47 commits
- Documentation/References — 46 commits
- Source/Events.Store.MongoDB — 30 commits
- .github/workflows — 12 commits
- Integration/Tests — 11 commits
- Specifications/Events.Processing — 9 commits
- Source/Server — 7 commits
- Source/EventHorizon — 5 commits
- Integration/Shared — 4 commits
- Documentation/Concepts — 3 commits
- Source/Services — 3 commits
- Configurations/compose — 2 commits
- Docker/Development — 2 commits
- Integration/Benchmarks — 2 commits
- Source/Actors — 2 commits
- Source/CLI — 2 commits
- Specifications/Events.Store.MongoDB — 2 commits
- Configurations/consumer — 1 commit
Notable commits
- fix: Fix CI port issue
- fix: Fix for incorrect scope in stream processor state retrieval
- fix: Fix incorrect dependency injection to management API
- fix: Fixed MongoDB image ref
- fix: Fixed assertion
- fix: Fixed edge case in catchup logic which could cause processing to stall.
- fix: Fixed edge case where processor would not retry old events before new events were present. This was fixed by not waiting for the first event to be present before starting the processor.
- fix: Fixed event horizon consumer state mapping, added EventLogSequence metadata.
- fix: Fixed issue in eventlogstream-subscriptions to ensure correct subscription cancellation.
- fix: Fixed issue where the buffer was unbounded when processing catch-up events in stream processors
- fix: Fixed log statement
- fix: Fixed missing response in reprocess command
- fix: Fixed specifications
- fix: Fixed stream ordering when using DB's that do not use the natural sort order of _id.
- fix: Fixed test assertions
- fix: Fixed test assertions
- fix: Merge pull request #755 from dolittle/management-api-fix
- fix: Merge pull request #768 from dolittle/atlas-fix
- fix: Version fixes, cleanup
- change: "Add version 8.9.2 to changelog"
- …and 280 more
API surface
- 4 HTTP endpoints (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
dolittle/Runtime was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 8a86b7f7eb93129dc534db224bfabdf3e6622a59 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.