hirethunk / verbs

Verbs is an event sourcing package for PHP artisans
https://verbs.thunk.dev
MIT License
412 stars 32 forks source link

[Bug]: Something is wrong with states after replay #178

Closed DanielCoulbourne closed 2 weeks ago

DanielCoulbourne commented 2 weeks ago

What happened?

For some reason after truncating verb_snapshots and then replaying events, states are not updating correctly when new events are applied.

Weirdly, snapshots ARE being updated correctly. Check out this code below...

How to reproduce the bug

<?php

use Thunk\Verbs\Event;
use Thunk\Verbs\State;
use Thunk\Verbs\Facades\Verbs;
use Illuminate\Support\Facades\DB;
use Thunk\Verbs\Attributes\Autodiscovery\StateId;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Thunk\Verbs\Models\VerbSnapshot;

class CountState extends State
{
    public int $count = 0;
}

class CountUp extends Event
{
    #[StateId(CountState::class)]
    public int $count_id;

    public function apply(CountState $count)
    {
        $count->count++;
    }
}

uses(RefreshDatabase::class);

it('does something', function () {
    $id = snowflake_id();
    Verbs::commitImmediately();
    $count = CountState::load($id);

    CountUp::fire(count_id: $id);

    expect($count->count)->toBe(1);

    DB::table('verb_snapshots')->truncate();
    Verbs::replay();

    CountUp::fire(count_id: $id);
    CountUp::fire(count_id: $id);

    expect(VerbSnapshot::firstWhere('state_id', $id))
        ->data
        ->toBe(json_encode(['count' => 3]));

    expect($count->count)->toBe(3);
});

Package Version

0.6.2

PHP Version

8.3

Laravel Version

11.x

Which operating systems does with happen with?

macOS

Notes

I dont have time to fully figure this out this moment but it has something to do with state rehydration from snapshots after a replay

DanielCoulbourne commented 2 weeks ago

Actually if you just do $count->fresh() before checking, this doesnt happen. This isnt a real problem