Author Archives: bullgare
Golang’s sync.Map internals
Great article on the topic — https://victoriametrics.com/blog/go-sync-map/index.html. The whole series of articles is solid, so please take a look if you are interested. Let me share the most important insights. How it works Internal structure is:
1 2 3 4 5 6 |
type Map struct { mu Mutex read atomic.Pointer[readOnly] dirty map[any]*entry misses int } |
MVC, MVP, MVVM, MVVM-C, and VIPER architecture patterns comparison
Great diagram comparing MVC, MVP, MVVM, MVVM-C, and VIPER architecture patterns from ByteByteGo: They also provide the following description: — MVC, the oldest pattern, dates back almost 50 years — Every pattern has a «view» (V) responsible for displaying content and receiving user input — Most patterns include a «model» (M) to manage business data …
Cleanlinter — my first golang linter
I’ve implemented my first go linter, called cleanlinter — https://github.com/bullgare/cleanlinter. It’s a simplistic linter to check golang project internal imports according to Clean Architecture pattern. Installation
1 |
go install github.com/bullgare/cleanlinter/cmd/cleanlinter@latest |
Usage
1 2 3 4 5 6 |
cleanlinter \ -cleanlinter_path_to_domain=github.com/bullgare/cleanlinter/test/testdata/src/project_correct/internal/domain \ -cleanlinter_path_to_usecase=github.com/bullgare/cleanlinter/test/testdata/src/project_correct/internal/usecase \ -cleanlinter_path_to_adapter=github.com/bullgare/cleanlinter/test/testdata/src/project_correct/internal/adapter \ -cleanlinter_path_to_infra=github.com/bullgare/cleanlinter/test/testdata/src/project_correct/internal/infra \ ./... |
To be honest, writing proper integration tests made much more time than just writing the linter. Articles, discussions, examples that helped me: https://developer20.com/custom-go-linter/ https://stackoverflow.com/questions/72933175/go-get-filepath-from-ast-file https://github.com/bkielbasa/cyclop/blob/master/pkg/analyzer/analyzer.go https://github.com/alingse/asasalint/blob/main/asasalint_test.go
Heroes 3 on a Steam Deck
That’s how you install it: original — https://www.reddit.com/r/heroes3/comments/18xql2r/heroes_of_might_and_magic_iii_horn_of_the_abyss/ copy (better structured but a bit less detailed) — https://heroes3wog.net/steam-deck-installation-guide-heroes-iii-horn-of-the-abyss-v1-7/ That’s how you add a Jebus Outcast template — https://www.h3templates.com/templates/jebus-outcast.
DDD/Clean Architecture go linters
Origin (in Russian) Tech talk (paid access only, unfortunately): https://conf.ontico.ru/online/hl2023/details/5206668 Presentation: https://docs.google.com/presentation/d/1n5jCie-9tBw3QEEF6NsNco4mS9xYkg52/edit#slide=id.g29c6e2d30cb_0_169 Linters Dependencies between layers: https://github.com/OpenPeeDeeP/depguard https://github.com/fe3dback/go-arch-lint/ You can also check mine (very simplistic) — https://blog.bullgare.com/2024/06/cleanlinter-my-first-golang-linter/ Others: https://github.com/nishanths/exhaustive — to check using all microtypes in enums/switches. https://github.com/go-simpler/musttag + https://github.com/maranqz/golangconf2023/blob/main/tags/rules.go — to prevent using struct tags in Domain models (Value Objects). https://github.com/maranqz/gopublicfield — to prevent …
Protobuf: safer usage for buf
A drop-in replacement for buf issued by Ozon. Repository: https://github.com/easyp-tech/server Presentation (for subscribers only, unfortunately): https://conf.ontico.ru/online/hl2023/details/5206585
Maps internals in Go
Idea Map is passed as a value, but it consists of a pointer to hmap which has all the details on map implementation. So, if you change/add to map, it will be reflected everywhere. And that’s why you cannot assign to an uninitialized map (no memory allocated, no hash seed generated yet). runtime/map.go
1 2 3 4 5 6 7 8 9 |
type hmap struct { count int // # live cells == size of map. Must be first (used by len() builtin) B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items) hash0 uint32 // hash seed buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0. oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated) } |
Buckets …
mountebank for mocking and stubbing http services (rest+graphql+grpc)
http://www.mbtest.org/docs/api/stubs can be used to stub http(s)/tcp/smtp protocols. And has community plugins for grpc, graphql, websockets. You can configure it with imposters.ejs like below:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "port": 80, "protocol": "http", "defaultResponse": { "statusCode": 404, "headers": {} }, "stubs": [ <% include stubs/service1.json %>, <% include stubs/service2.json %>, <% include stubs/service3.json %> ] } |
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 |
version: "3.5" services: mountebank: container_name: mountebank image: jkris/mountebank:latest volumes: - ./:/mountebank ports: - "15050:80" command: --configfile /mountebank/imposters.ejs --allowInjection |
HTTP Toolkit — another alternative to Charles Proxy for http calls interception
https://httptoolkit.com/ It has a free version which does something similar to Charles Proxy, so you can hack into the middle of any request/response according to the rules specified.
YouType to show flag icon for current locale on MacOS
It has reacher functionality, but I use it only to show a flag for my current locale in a tray. https://github.com/freefelt/YouType