macula-neuroevolution-esdb

Bridge library between macula-neuroevolution lineage tracking and erl-esdb-gater.

Hex.pmDocumentation

Overview

This library provides an implementation of the neuroevolution_lineage_events behaviour using erl-esdb-gater as the event store backend. It enables persistent genealogy tracking for evolved neural networks.

Performance Design

Lineage tracking NEVER blocks the evolution loop:

Architecture

macula-neuroevolution          macula-neuroevolution-esdb         erl-esdb-gater
+---------------------+       +------------------------+       +-----------------+
| neuroevolution_     |       | esdb_lineage_backend   |       | esdb_gater_api  |
| lineage_events      |<------| (fire-and-forget)      |------>| append_events   |
| (behaviour)         |       |     spawn -> write     |       | (async)         |
+---------------------+       +------------------------+       +-----------------+

Installation

Add to your rebar.config:

{deps, [
    {macula_neuroevolution_esdb, "~> 0.1.0"}
]}.

Usage

Initialize the Backend

Config = #{store_id => my_lineage_store},
{ok, State} = esdb_lineage_backend:init(Config).

Persist Lineage Events (Fire-and-Forget)

%% Single event - returns immediately
Event = #{
    event_type => offspring_born,
    individual_id => <<"ind-001">>,
    parent_ids => [<<"ind-000">>],
    generation => 1
},
ok = esdb_lineage_backend:persist_event(Event, State).

%% Batch of events - returns immediately
Events = [
    #{event_type => fitness_evaluated, individual_id => <<"ind-001">>, fitness => 0.85},
    #{event_type => mutation_applied, individual_id => <<"ind-001">>, mutation_type => weight_perturb}
],
ok = esdb_lineage_backend:persist_batch(Events, State).

Read Events (For Recovery Only)

%% WARNING: This blocks! Only use for recovery/replay, not during evolution.
StreamId = <<"individual-ind-001">>,
Opts = #{from => 0, limit => 100, direction => forward},
{ok, Events} = esdb_lineage_backend:read_stream(StreamId, Opts, State).

Subscribe to Events

%% Subscribe to individual&#39;s events (for projections)
StreamId = <<"individual-ind-001">>,
ok = esdb_lineage_backend:subscribe(StreamId, self(), State).

%% Receive events
receive
    {lineage_event, StreamId, Event} ->
        handle_event(Event)
end.

Stream Routing

Events are automatically routed to streams based on entity type:

Event Types Stream Pattern
Birth, death, fitness, mutations individual-{id}
Speciation, lineage divergence species-{id}
Generation, capacity events population-{id}
Coalition lifecycle coalition-{id}

Supported Events

Individual Events

Species Events

Population Events

Coalition Events

Dependencies

License

Apache License 2.0