Programiści tacy jak my
Cześć!
Jeśli śledzisz mnie na Twitter to mogło Ci się rzucić w oczy, że jestem fanem biblioteki System.Text.Json. Przy weekendzie nasza relacja nabiera bliskości. Aktualnie pracuję w Marten nad wsparciem tej biblioteki i jestem przeszczęśliwy. Tak bardzo, że dałem o tym znać światu np. tutaj https://twitter.com/oskar_at_net/status/1348227787497287681. Coś niesamowitego!
W świecie .NET do niedawna standardem była biblioteka Newtonsoft Json.NET. Została napisana przez Jamesa Newton-Kinga. Jest to jeden z nielicznych przykładów gdzie biblioteka Open Source zaczęła być używana przez Microsoft w jego projektach. Normalnie Microsoft “Not invented here”. Czyli woli coś zrobić od zera przez siebie niż użyć czegoś gotowego, ale czegoś nad czym nie ma kontroli. No prawie - Microsoft zatrudnił Jamesa Newton-Kinga, po czym praktycznie przestał On utrzymywać Json.NET zajmując się ciekawszymi dla niego rzeczami (np. gRPC).
Czy można mieć pretensje do chłopa? Nie bardzo. Próbował jakoś uzyskać finansowe wsparcie, ale niespecjalnie mu to “pykło” https://github.com/JamesNK/Newtonsoft.Json/pull/387. Dodatkowo idzie się zmęczyć będąc pracą po godzinach nad biblioteką, na której stoi cały .NETowy Json…
Microsoft stwierdził, że “może ten Json.NET fajny, ale my to zrobimy lepiej.”. Harder, better, faster, stronger!. W końcu co to za wielkie mecyje napisać swój parser. Bułka z masłem. Jak pomyśleli tak zrobili i wypuścili napisany od zera parser System.Text.Json.
Dlaczego o tym piszę? Bo wg mnie popełnione zostały tam wszystkie błędy, które często widziałem w swojej karierze przy nowych projektach.
- “Never underestimate the value of working software” - Newtonsoft Json.NET może nie był demonem szybkości, były szybsze serializery, ale był w sam raz. Nie odstawał. Do aplikacji biznesowych jak znalazł. Przez lata dostał wsparcie i wszelkie możliwe dziwne produkcyjne przypadki. Microsoft nie docenił tego w jak wielu miejscach JSON jest używany w aplikacjach. Jak duże jest spektrum tego jak ludzie go przetwarzają i ile potrafi Newtonsoft Json.NET. Łatwo jest napisać coś wydajnego jeśli się nie wspiera większości przypadków. Jest to jak najbardziej w porządku, żeby skupić się na tylko specyficznych scenariuszach - wtedy można osiągnąć najlepsze optymalizacje, ale nie jeśli (nieoficjalnie) ubijasz działającą bibliotekę i szumnie obwieszczasz jej następcę.
- Architekci nie znający biznesu - okazało się, że ludzie, którzy tworzyli design stwierdzili, że oni wiedzą najlepiej. Cel był szczytny - np. usunięcie wszystkich dziwnych edge case’ów. Ale niestety wyszedł brak wiedzy o rzeczywistych przypadkach, nawet z własnego poletka. Sam widziałem jak jeden z architektów się zżymał, że co to za ludzie chcą numery jako string zapisywać. Tylko chyba nie wie, że tym long/bigint w JavaScript się nie zmieści do JSONowego numeru… Tak samo, nie wpadli, że ludzie nie robią tylko prostych DTO gdzie są publiczne właściwości. Przykładów można by mnożyć. My często też jak siadamy do projektu, szczególnie jak chcemy przepisać stary to mówimy “Proste! W tym starym narobili syfu, pełno rzeczy niepotrzebnych. Ja to przepiszę i będzie lepiej”. Potem im dalej w las tym częściej patrząc w stary kod myślimy “aaaa, to dlatego tak to zrobili!“.
- Szara rzeczywistość nas dopada - Niestety zachłyśnięci własną zajebistością nie robimy dobrej decyzji przed podjęciem decyzji architektonicznej. Często nasz design opiera się na optymistycznych założeniach. Często one są podstawą, którą trudno zmienić w późniejszym etapie. Potem dopiero widzimy, że to wcale nie było tak proste jak nam się wywdawało. Ja przy pierwszej próbie użycia System.Text.Json miałem okazję zostać kontrybutorem .NET bo okazało się, że testów to tam na podstawowe przypadki prawie nie było (jak np. cykle przy derserializacji…) - https://github.com/dotnet/corefx/pull/37611. Potem czas nas goni i za późno na odkręcanie tego wszystkiego. Dlatego użycie System.Text.Json to jest tak naprawdę pudełko czekoladek. Nigdy nie wiesz na jaką “optymalizację” się nadziejesz. Tak naprawdę dowiesz się przy użyciu czy to jest wspierane czy nie bo może autorzy stwierdzili, że akurat na to Ci nie pozwolą, bo tutaj sobie chcieli coś zoptymalizować. A na dużo rzeczy nie pozwalają…
- “Dlaczego to tyle zajmie? Przecież to tylko jeden insert do tabeli.” - Terminy zaczynają nas gonić, robota rozgrzebana. Już wiemy, że mocno się przeliczyliśmy, teraz już chcemy się tylko tego pozbyć i wypchać, żeby nam dali spokój. Tutaj insert do tabeli, tutaj kolejny if. W System.Text.Json ma to objaw - dorzućmy kolejny atrybut. Pole zamiast właściwości, dawaj atrybut. Niepubliczne właściwości, też atrybut. Wsparcie dla konstruktora z parametrami - dorzućmy atrybut. Ale to nie zdziała dla typów anonimowych! Nie ważne - mamy deadline, może nie zauważą, jak nie to się powie, że dostaną w kolejnej wersji. Znasz tego typu dyskusje ze swoich projektów?
- Ratowanie sytuacji - Wypchaliśmy w końcu soft łokciami i kolanem. Wiemy, że jest źle, no ale zawsze dostaniemy przecież czas na bugfixing. Może uda się przy poprawce błędów wepchać jakieś brakujące funkcjonalności. Jak nie to się powie, że w kolejnej wersji. Wyprzemy się tego co mówiliśmy. Wtedy byliśmy innmi ludźmi. W System.Text.Json optyka się też zmieniła z https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/ na https://github.com/dotnet/runtime/issues/29690#issuecomment-685902880. Na testy czasu nie było wystarczająco, ale to nic - klient sobie przetestuje.
Czemu się pastwię nad System.Text.Json? Bo mnie boli. Nie będę ukrywał, że wg mnie takiego produktu nie powinno się wypuszczać na świat. Szczególnie z takim marketingiem. Irytuje mnie ile pracy i prób musiałem włożyć w to, żeby Marten go wspierał (zobacz: https://github.com/JasperFx/marten/pull/1685/files). Oczywiście moglibyśmy używać Newtonsoft Json.NET dalej, ale jak to robić gdy praktycznie nie ma już wsparcia?
No ale tak naprawdę moja własna irytacja jest tutaj sprawą drugorzędną. Wbrew pozorom jest to mail ku pokrzepieniu serc. Nawet w takich firmach jak Microsoft są programiści tacy jak my. Robiący te same błędy i zmagającymi się z tego typu samymi problemami.
Głowa do góry, w kolejnej wersji będzie lepiej!
Pozdrawiam Oskar
p.s. nie tylko z newsletterem udaje mi się utrzymywać regularność, co mnie cieszy! Nowy wpis na blogu, tym razem pół żartem pół serio o tym co sms do byłej m wspólnego z Event-Driven Design - https://event-driven.io/pl/what_texting_ex_has_to_do_with_event_driven_design/ p.s.2 Jest poniedziałeczek to jest i nowe Architecture Weekly! https://github.com/oskardudycz/ArchitectureWeekly#1st-february-2021 Znajdziesz tam m.in. link do artykułu, który opisuje skąd się wzięło powiedzenie “Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”