Category Programming
In Go, we can refer to variables using value or pointers. Sometimes, it’s hard to answer which approach is more suitable. At the first place, you should learn about general rules. Value semantic should be used every time when copying the value make sense in the logic of your code. For example, every value object should be passed by value. If you have a struct Money then it’s possible (and also make sense) to have, at the same time, multiple 10$ in your code.
In the garbage-collected world, we want to keep the GC overhead as little as possible. One of the things we can do is limiting the number of allocations in our application. How to achieve that? There’s sync.Pool which caches allocated but unused items for later reuse. The Pool can become very useful when you have multiple parallel operations that can share the same piece of memory between them. The real power of it is visible when you have frequent allocations and deallocations of the same data structure.
The varnish is a well-known HTTP accelerator. As the continuation of the GoInPractice series, today I’ll show how you can build a simple (and naive) varnish implementation in Go. Some of the code is reused from Writing a reverse proxy so if you don’t understand something, I recommend taking a look at the blog post. We’ll split our project into a few parts. The first one will be the caching mechanism.
Some time ago, I found a video called Building a DIY proxy with the net package. I recommend watching it. Filippo Valsorda builds a simple proxy using low-level packages. It’s fun to watch it but I think it’s a bit complicated. In Go, it has to be an easier way so I decided to continue writing series Go In Practice by writing a simple but yet powerful reverse proxy as fast as it’s possible.
Go is perfect for network applications. Its awesome standard library helps a lot in writing such software. In this article, we’ll write a simple TCP scanner in Go. The whole programm will take less than 50 lines of code. Before we’ll go to practice - a little theory. Of course, the TCP is more complicated than I describe but we need just basics. The TCP handshake is three-way. Firstly, the client sends the syn package which signals the beginning of a communication.
In Go 1.13 all modules are provided using a proxy. The proxy caches dependencies what helps to make sure that the version of an external dependencies will never change. If the vendor remove the version and create a new one with the same version, only the first one will be provided. Proxy improves the performance of downloading dependencies as well so it’s useful to have such functionality in the ecosystem.
Structuring the source code can be as challenging as writing it. There are many approaches to do so. Bad decisions can be painful and refactoring can be very time-consuming. On the other hand, it’s almost impossible to perfectly design your application at the beginning. What’s more, some solutions may work at some application’s size and should the application develop over time. Our software should grow with the problem it’s solving.
Testing is one of the hardest stuff in programming. Today trick will help you organize your tests and the production code. Let’s assume you have a package called orders. When you want to separate the package for tests from the production code you can create a new folder and write tests there. It will work but there’s a more clearer way - put your tests to the folder with you package but suffix the package’s name in tests with _test.
While working with structures, there’s a possibility to initialize the structure without providing the keys of fields. type SomeSturct struct { FirstField string SecondField bool } // ... myStruct := SomeSturct{"", false} If we want to force other (or even ourselfs) to explicitly providing the keys, we can add _ struct{} in the end of the structure. type SomeSturct struct { FirstField string SecondField bool _ struct{} } // COMPILATION ERROR myStruct := SomeSturct{"", false} The code above will produce too few values in SomeSturct literal error.
While developing a library, we create a directory structure to keep the code organized. However, some exported functions or struct should not be used by users of the library. The achieve that, call the package internal. . ├── bar │ ├── bar.go │ └── internal │ └── foobar.go ├── internal │ └── foo.go └── main.go In the example above, the foo.go can be included only in the main.go. What’s more, only the bar.