I’ve self hosted an n8n to automate video uploads to youtube. The idea was pretty simple - when I put an mp4 file in a specific dir on my nas, n8n would pick it up, as well as a metadata.json file. The metadata file would contain things like the title and description, and it would upload this to youtube. I started creating this automation and pretty soon had something that resembled the finished workflow. I started testing it out. However, I ran into a problem. I had a Read/Write files from...| Dizzy zone
Sometimes I have to install Node on my machine for work, or a personal project. This occurs rarely, so I keep forgetting how to do it. So I did what I usually do, and Googled how to install nvm. To my surprise there’s a sponsored result, which immediately triggers a red flag: This link leads to a repo in Github. It has the following readme - I’ve omitted the domain and path:| Dizzy zone
I find Go’s error handling refreshingly simple & clear. Nowadays, all I do is wrap my errors using fmt.Errorf with some additional context. The pattern I tend to use most of the time just includes a function/method name, like so: funcsomeFunction() error { err:=someStruct{}.someMethod() returnfmt.Errorf("someFunction: %w", err) } typesomeStructstruct { } func (sssomeStruct) someMethod() error { returnfmt.Errorf("someMethod: %w", errors.New("boom")) } If I now call someFunction, the error - ...| Dizzy zone
For work, I was going to store some hashed tokens in a database. I was going to keep it simple and go with HMAC-SHA256 for it but having recently read Jean-Philippe Aumasson’s book “Serious Cryptography” I remembered that BLAKE2 should be quicker: BLAKE2 was designed with the following ideas in mind: … It should be faster than all previous hash standards Cool, I thought, let’s consider BLAKE2 then. First, let’s write a simple benchmark to see just how much faster BLAKE2 would be t...| Dizzy zone
My homelab consists of 4 machines currently. When choosing them I tried to be energy conscious - using hardware which would not consume too much electrical power, while still trying to maintain the up-front cost low. These are mostly older systems and I was unable to find decent power consumption numbers for them. The specs 1x MSI Cubi 3 Silent NUC CPUDual-core i5-7200U RAM2×16GB 2x Lenovo ThinkCentre M910 Tiny| Dizzy zone
I’ve been using Umami analytics on this blog for quite some time now. I self host an instance on my homelab. I spent a bit of time researching self-hosted analytics and generally they had a few issues. First, I’d like the analytics platform to be privacy focused. No cookies, GDPR compliant, no PII. Umami checks this mark. Second, many of the alternatives had quite a bit of hardware resource overhead once hosted. They would either consume a ton of memory, the cpu usage would be high or req...| Dizzy zone
After reading the technicalwriting.dev post on embeddings I thought to myself - this seems like something that I can implement quite quickly and would serve as a good starting point for some hands on experience with machine learning. I want to start small, so something as simple as filling the related posts section of this blog seems like an ideal candidate to get my hands dirty. This blog is made with Hugo and uses the related content feature which provides a list of related posts based on t...| Dizzy zone
About cache stampedes I often end up in situations where I need to cache this or that. Often, these values are cached for a period of time. You’re probably familiar with the pattern. You try to get a value from cache, if you succeed, you return it to the caller and call it a day. If the value is not there, you fetch it(most likely from the database) or compute it and the put it in the cache. In most cases, this works great. However, if the key you’re using for your cache entry gets access...| Dizzy zone
SQLC has become my go-to tool for interacting with databases in Go. It gives you full control over your queries since you end up writing SQL yourself. It then generates models and type safe code to interact with those queries. I won’t go over the basics here, if you feel like it you can try their interactive playground. Dynamic queries Frequently I end up needing to filter the data by a set of fields in the database. This set of fields is often determined by the caller, be it via REST API o...| Dizzy zone
I’ve seen many discussions about whether Go should add enum support to the language. I’m not going to bother arguing for or against but instead show how to make do with what we have in the language now. A very short enum intro Enumerated types, or enums, represent finite sets of named values. They are usually introduced to signal that variables can only take one of the predefined values for the enum. For example, we could have an enum called Colors with members Red, Green, Blue. Usually, ...| Dizzy zone
When you install TrueNAS SCALE your NAS runs a Netdata. You can verify that by executing systemctl status netdata in the TrueNAS shell. I use Netdata to monitor my homelab and have a parent set up for long term metric storage. I’d love to configure the NAS to also push metrics to a parent, so that I can access them all from a single place. Normally, if you want to set up streaming in Netdata it’s enough to edit /etc/netdata/stream.conf. However, I wouldn’t recommend doing this on a True...| Dizzy zone
I was working on a project that uses PostgreSQL and as part of my task I needed to write a migration. The migrations are written as plain SQL and applied using the migrate library. The migration itself was not that complex, some rows needed to be updated where a column matched one of the values in a list. In my rush, I’ve opted for a rather simple query that went something like this:| Dizzy zone
I’ve written in the past that this blog is a playground for me to try various tools and play with code around it. Jenkins has been my choice as the CI for it since the start, mostly since it was something I’m used to. However, I’ve also stated that running it on an old laptop with no real backups is a recipe for disaster. I have since rectified the issue by hiding the laptop under a box in a closet but that meant moving away from Jenkins to something that’s lighter and more portable. ...| Dizzy zone
I’ve recently had my birthday and as a gift decided to give myself a NUC. The intention here is that I could replace the old laptop running Jenkins and Grafana with something that’s a bit more silent and in a smaller form factor. Note that I’m not affiliated with any of the hardware manufacturers in any way shape or form. The planned change The laptop I’ve been using for Jenkins has become rather critical for this blog and a few side projects I’ve got. This meant that I first needed...| Dizzy zone
I’ve written about the infrastructure behind this blog in a previous post and the major issue with it currently is the old laptop I have at home that’s running the Jenkins instance. I really have no way of backing it all up. I’ve asked around a bit and the reddit thread I’ve made pointed me towards moving it all towards Ansible. Since people are using Ansible at work I thought it would be appropriate for me to try it as well.| Dizzy zone
Go comes with great tools for profiling out of the box. It’s one of the features I’ve come to love. I’m not going to go into detail about pprof, but if you need a primer, Julia Evans has a great post about it on her blog. Instead, I’ll try and show a real world example of the optimizations you can make using pprof. I’ll use pprof on mouthful, a gin based server, to see what I could do to make it just a bit faster. It turns out I can detect a rather stupid mistake I’ve made.| Dizzy zone
There are quite a few components to this blog now. There’s an AWS S3 bucket the blog gets served from, there’s a backend service responsible for the mouthful comments, there’s another instance of the service for the mouthful demo page, with another S3 bucket to serve the page for it. There’s also a yet unused service living in the same “cluster” as these two(It’ll get added to this blog soon™). There’s quite a few private github repositories that in unison with a Jenkins ins...| Dizzy zone
When writing Go code, I often end up with lots of enums that I use to fork my logic in a switch statement. Take this enum: typeMyEnumintconst ( OneMyEnum = iotaTwoMyEnum = iotaThreeMyEnum = iotaFourMyEnum = iotaFiveMyEnum = iota) } I’ll then end up with a switch in a part of my code, like so switchmyEnum { caseOne: err:=DoSomeOtherStuff() iferr!=nil { returnerr } caseTwo: err:=DoSomeMagicalStuff() iferr!=nil { returnerr } caseThree: err:=DoSomeExoticStuff() iferr!=nil { returnerr } caseFour...| Dizzy zone
When I created mouthful, I was intending it to be rather light and not feature rich but after getting a few feature requests getting in, I’ve decided to expand it. One of the issues was a request to reuse logon credentials for the admin panel. For that, I’ve needed OAuth. I did not have much prior experience with OAuth, so it did intimidate me a bit. However, after implementing OAuth for mouthful, I can say that nowadays - it’s rather easy including OAuth in your applications as well. I...| Dizzy zone
I haven’t been blogging much lately. That’s due to the fact that most of my spare time went to creating mouthful - a commenting server that I’ve since switched this blog to. Before that I was using isso. Here’s why I did it. The issue with isso While I really like isso, there’s one problem that kills it for me. Under no load, the backend consumes nearly 50MB of memory on my server. You might say that 50MB is nothing nowadays but I disagree. I’m running everything under AWS t2.nano...| Dizzy zone
<rant> I absolutely despise OpenApi(well, swagger. I’ll call it swagger since it was that for most of my career). It’s supposed to make the process of creating and documenting an API easier. But does it really?… Here’s what I think about it. Writing the swagger schema is so damn tedious From my experience when someone mentions swagger, you’ll get dragged into design first - code later mindset rather quickly. While it sounds good on paper the practical implications of writing a swagg...| Dizzy zone
There are quite a few IDE choices for Go. I’m not going to list them all, but here are my prefered ones with the reasoning behind it. The free option VS code is my main IDE as of late. It does not matter if I code Go or Node, I always prefer to go with VS code. I used to use Atom for it’s extensibility and the amount of packages avaialble. But recently, I’ve felt that the quality of packages and the editor itself is better on VS code. That might be due to the fact that it has the backin...| Dizzy zone
So I’ve had this raspberry pi 3 laying around in my closet for a year or a bit more now. While I thought I’d use it for automating something such as monitoring our plants for changes in soil moisture that did not come to fruition. With the start of this blog and the increase in tooling around it, I really needed something to run any sort of CI platform. I tend to host everything under AWS so that everything is under one roof. Issue there is that it might become rather expensive if you sta...| Dizzy zone
I will occasionally come across a post like this on Reddit or other social platforms. This post is an attempt to encourage people to try and get their careers in IT started. This is how it all started for me… Initial apprehension of programming After finishing high school, I ended up studying informatics at Vilnius University. The choice was not easy, I was drifting heavily towards economics and physics, as well as considering the more humanitarian part of with focus on business and busines...| Dizzy zone
Since this post got quite a bit of traction, I decided to update it by rerunning all the benchmarks as well as adding GO’s fasthttp and Node’s express to the comparison. I came across this blog post on ayende.com. Here Oren Eini tries to see how far he could push a simple ipify style of api on an EC2 by running a synthetic benchmark. He hosts the http server on a T2.nano instance and then uses wrk to benchmark it from a T2.small instance. After reading this, I thought to myself - surely ....| Dizzy zone
Defer is the golang’s version of the more familliar finally statement of the try/catch block in languages like Java and C#. The defer allows you to perform actions when surrounding function returns or panics. Unlike finally blocks though it does not need to be placed at the bottom of the code block. You can also have multiple defer statements in a single function body. This allows for handy clean up of resources. It does have its downsides though. It does add overhead so using it everywhere...| Dizzy zone
I was looking for a way to add commenting functionality to the blog. The obvious candidate was Disqus but I did not choose it for 2 reasons: It’s too heavy(at around 200KB) It contains ads The weight itself would kill my quest for page speed instantly.So I set up to find a way to provide commenting ability on the blog. I knew this would probably lead me to a self-hosted solution but that did not scare me. Requirements were quite simple:| Dizzy zone
I’ve been using Go as my main programming language at work for the last 6 months. Here’s why I absolutely adore the language. It’s simple Go is remarkably simple. It’s an object oriented programming language but instead of the more typical classes you find in C# or Java it only has structs. Structs cannot inherit, meaning you can’t end up in inheritance hell. I won’t go into detail why inheritance is bad, but if you want an explanation Inheritance is Inherently Evil is a good read...| Dizzy zone
An explanation As mentioned in my previous post, I really wanted to optimize my hexo blog for speed. I’ve started a new project and decided hexo would be a good fit for it. Since I’ve grown used to hexo, it will make development faster. Albeit it’s not a blog I’m working on, but a webpage for a local blacksmith. That will involve quite a few images and just a few text entries/pages. Being able to deploy to S3 is also a benefit - no need to manage anything - and since the webpage is go...| Dizzy zone
So me and my girlfriend have been playing with the idea of starting a blog for quite some time now. Having a day off I’ve decided to put it to good use and start creating one. Being a developer I’ve had a few concerns when it came to choosing a blog framework: I’m a control freak so I’d prefer hosting it myself. Blogging platforms are out of the question. I like markdown - the blog must support it. It must be lightweight. It must be easily deployable to s3 static website hosting. I sh...| Dizzy zone
For many years now I’ve had at least one machine at home which would work as a server to host some apps. In the last couple of years I’ve been getting more into it which has led me to purchase additional hardware. I’ve decided it would be nice to document my journey so I’ll try to make a post like this - detailing the setup that I currently have with both the hardware and the software once a year.| Dizzy zone
There are books & many articles online, like this one arguing for using Postgres for everything. I thought I’d take a look at one use case - using Postgres instead of Redis for caching. I work with APIs quite a bit, so I’d build a super simple HTTP server that responds with data from that cache. I’d start from Redis as this is something I frequently encounter at work, switch it out to Postgres using unlogged tables and see if there’s a difference.| Dizzy zone