Skip to content

Issue #131 (ginkelsoft-development/buildora): ColumnBuilder een in-memory cache per resource-class geven zodat defineFields() niet bij elke datatable-request opnieuw wordt aangeroepen. - #185

Open
zyra-ginkelsoft[bot] wants to merge 2 commits into
mainfrom
zyra/issue-131-ginkelsoft-development-buildor-8993c293
Open

zyra-ginkelsoft[bot] wants to merge 2 commits into
mainfrom
zyra/issue-131-ginkelsoft-development-buildor-8993c293

Conversation

@zyra-ginkelsoft

Copy link
Copy Markdown
Contributor

Nu bekijk ik hoe tests draaien en of composer/phpunit al werkt.vendor bestaat nog niet. Laten we composer install draaien.Composer install gelukt. Nu draai ik de bestaande tests baseline om te zien of alles slaagt vóór mijn wijziging.Baseline is groen. Nu implementeer ik de cache in ColumnBuilder.Nu schrijf ik de test. Ik maak een test-directory tests/Unit/Datatable met een test-resource die telt hoeveel keer getFields() (het pad dat defineFields()-resultaten aanlevert) wordt aangeroepen.Alle 39 tests slagen. Nu lint en typecheck draaien.Lint is schoon. Nu de PHPStan-analyse.Deze fouten bestonden al vóór mijn wijziging (andere bestanden). Even bevestigen dat mijn bestand niet in de lijst staat en dat dit een pre-existing issue is (baseline check).Bevestigd: deze lintfouten zijn pre-existing en niet door mijn wijziging veroorzaakt. Mijn ColumnBuilder.php is schoon. Nu de volledige PHPStan-analyse.Geen fouten in ColumnBuilder.php — de 59 fouten zijn allemaal pre-existing in andere bestanden (typecheck was al niet volledig schoon vóór mijn wijziging). Nu bekijk ik of er al een .zyra/proef.sh bestaat.Het bestaat al en is aangepast op deze package (Testbench-based). Laten we het testen om te bevestigen dat het nog werkt.Het proefscript werkt prima (HTTP 200). Nu commit ik het werk.Laatste check: volledige testsuite nog eens draaien op de gecommitte staat, en status bevestigen.Alles staat gecommit, working tree is schoon.

Samenvatting

Wat ik deed:
ColumnBuilder::build() doorliep bij elke aanroep (dus bij elke datatable-request) opnieuw alle fields van een resource — inclusief een extra loop per veld voor de zichtbaarheidscheck (isVisibleInTable), wat neerkomt op meerdere getFields()-aanroepen per build(). Ik heb een statische in-memory cache toegevoegd (private static array $columnCache), sleutel = get_class($resource). Bij een cache-hit geeft build() direct de eerder berekende kolommenarray terug zonder de velden opnieuw te doorlopen; bij een miss wordt zoals voorheen berekend en het resultaat opgeslagen. Ook een clearCache() toegevoegd (voor tests). De cache leeft per PHP-proces, geen invalidatie nodig zoals in het issue afgesproken — de kolomstructuur hangt alleen af van de fields-definitie van de resource-class, niet van instantie of record.

Hoe getest:
Nieuwe test tests/Unit/Datatable/ColumnBuilderTest.php met een test-double resource waarvan getFields()/defineFields() een teller bijhoudt:

  • eerste build()-aanroep bouwt de juiste zichtbare kolommen op;
  • een tweede build() met een nieuwe instantie van dezelfde resource-class laat de tellerstand niet stijgen (bewijst dat de fields niet opnieuw doorlopen worden dankzij de cache);
  • verschillende resource-classes krijgen elk hun eigen cache-entry (kolommen zijn niet gelijk aan elkaar, en beide classes hebben wél minstens één keer hun fields opgebouwd).

Volledige testsuite: 39 tests, 48 assertions, groen (was al 36/36 groen vóór mijn wijziging). Lint (phpcs PSR12) op ColumnBuilder.php is schoon; PHPStan level 5 op dat bestand geeft "No errors". De project-brede lint/analyse had al vóór mijn wijziging bestaande meldingen in andere bestanden (bevestigd via git stash) — die laat ik ongemoeid, buiten scope van dit issue.

Proefdraaien: .zyra/proef.sh bestond al en werkt (Testbench-gebaseerd, want Buildora is een package zonder eigen host-app): composer install, sqlite-db aanmaken, migraties, testbench serve op 0.0.0.0:$PORT. Getest met PORT=8123 → /buildora/install gaf HTTP 200.

Wat open staat:

  • De benchmark uit het issue is niet uitgevoerd/toegevoegd — die is optioneel en niet-blokkerend voor deze PR, zoals afgesproken.
  • De onderliggende O(n²) inefficiëntie in isVisibleInTable() (die getFields() per veld opnieuw aanroept) is niet aangepakt; de cache maskeert dit voor herhaalde build()-calls binnen hetzelfde proces, maar een losstaande opschoning daarvan zou een aparte, kleine PR kunnen zijn.
  • Geen cache-invalidatie geïmplementeerd (bewust, conform plan — cache is per proces).

Zyra added 2 commits September 3, 2026 11:07
ColumnBuilder::build() doorliep bij elke datatable-request opnieuw de
velden van een resource (o.a. dubbel via de zichtbaarheidscheck). Een
statische in-memory cache per resource-class zorgt dat dit werk maar
één keer per proces gebeurt; de kolomstructuur hangt alleen af van de
fieldsdefinitie van de class, niet van de instantie of het record.

Test toont aan dat een tweede build()-aanroep voor dezelfde
resource-class niet opnieuw door de velden gaat.
Logbestanden van phpunit, phpcs (ColumnBuilder + volledige src) en
phpstan (level 5, ColumnBuilder + volledige src) plus een proefdraai-log
van .zyra/proef.sh, ter onderbouwing dat de cache-wijziging in
ColumnBuilder groen is en geen nieuwe lint/typecheck-fouten introduceert.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants