Initial restructuring
This commit is contained in:
parent
c71d9f723b
commit
b1719e8d24
69 changed files with 1133 additions and 3 deletions
5
content/blog/_index.md
Normal file
5
content/blog/_index.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Posts"
|
||||
---
|
||||
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
142
content/blog/alex/index.md
Normal file
142
content/blog/alex/index.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
---
|
||||
title: "Automating Minecraft Server Backups"
|
||||
date: 2023-09-07
|
||||
---
|
||||
|
||||
I started playing Minecraft back in 2012, after the release of version 1.2.5.
|
||||
Like many gen Z'ers, I grew up playing the game day in day out, and now 11
|
||||
years later, I love the game more than ever. One of the main reasons I still
|
||||
play the game is multiplayer, seeing the world evolve as the weeks go by with
|
||||
everyone adding their own personal touches.
|
||||
|
||||
Naturally, as a nerd, I've grown the habit of hosting my own servers, as well
|
||||
as maintaining instances for friends. Having managed these servers, I've
|
||||
experienced the same problems that I've heard other people complaining about as
|
||||
well: backing up the server.
|
||||
|
||||
{{< figure src="./the-village.jpg" title="Sneak peak of the village we live in" >}}
|
||||
|
||||
## The Problem
|
||||
|
||||
Like any piece of software, a Minecraft server instance writes files to disk,
|
||||
and these files, a combination of world data and configuration files, are what
|
||||
we wish to back up. The problem is that the server instance is constantly
|
||||
writing new data to disk. This conflicts with the "just copy the files"
|
||||
approach (e.g. `tar` or `rsync`), as these will often encounter errors because
|
||||
they're trying to read a file that's actively being written to. Because the
|
||||
server isn't aware it's being backed up, it's also possible it writes to a file
|
||||
already read by the backup software while the other files are still being
|
||||
processed. This produces an inconsistent backup with data files that do not
|
||||
properly belong together.
|
||||
|
||||
There are two straightforward ways to solve this problem. One would be to
|
||||
simply turn off the server before each backup. While this could definitely work
|
||||
without too much interruption, granted the backups are scheduled at times no
|
||||
players are online, I don't find this to be very elegant.
|
||||
|
||||
The second solution is much more appealing. A Minecraft server can be
|
||||
controlled using certain console commands, with the relevant ones here being
|
||||
`save-off`, `save-all`, and `save-on`. `save-off` tells the server to stop
|
||||
saving its data to disk, and cache it in memory instead. `save-all` flushes the
|
||||
server's data to disk, and `save-on` enables writing to disk again. Combining
|
||||
these commands provides us with a way to back up a live Minecraft server: turn
|
||||
off saving using `save-off`, flush its data using `save-all`, back up the
|
||||
files, and turn on saving again using `save-on`. With these tools at my
|
||||
disposal, I started work on my own custom solution.
|
||||
|
||||
## My solution
|
||||
|
||||
After some brainstorming, I ended up with a fairly simple approach: spawn the
|
||||
server process as a child process with the parent controlling the server's
|
||||
stdin. By taking control of the stdin, we can send commands to the server
|
||||
process as if we'd typed them into the terminal ourselves. I wrote the original
|
||||
proof-of-concept over two years ago during the pandemic, but this ended up
|
||||
sitting in a dead repository afterwards. However, a couple of months ago, some
|
||||
new motivation to work on the project popped into my head (I started caring a
|
||||
lot about our world), so I turned it into a fully fletched backup tool! The
|
||||
project's called [alex](https://git.rustybever.be/Chewing_Bever/alex) and as
|
||||
usual, it's open-source and available on my personal Gitea instance.
|
||||
|
||||
Although Alex is a lot more advanced now than it was a couple of months back,
|
||||
it still functions on the same principle of injecting the above commands into
|
||||
the server process's stdin. The real star of the show however is the way it
|
||||
handles its backups, which brings us into the next section.
|
||||
|
||||
## Incremental backups
|
||||
|
||||
You could probably describe my usual projects as overengineered, and Alex is no
|
||||
different. Originally, Alex simply created a full tarball every `n` minutes
|
||||
(powered by the lovely [tar-rs](https://github.com/alexcrichton/tar-rs)
|
||||
library). While this definitely worked, it was *slow*. Compressing several
|
||||
gigabytes of world files always takes some time, and this combined with shaky
|
||||
hard drive speeds resulted in backups easily taking 5-10 minutes. Normally,
|
||||
this wouldn't bother me too much, but with this solution, the Minecraft server
|
||||
isn't writing to disk for the entire duration of this backup! If the server
|
||||
crashed during this time, all this data would be lost.
|
||||
|
||||
This called for a better method: incremental backups. For those unfamiliar, an
|
||||
incremental backup is a backup that only stores the changes that occurred since
|
||||
the last backup. This not only saves a ton of disk space, but it also greatly
|
||||
decreases the amount of data that needs to be compressed, speeding up the
|
||||
backup process tremendously.
|
||||
|
||||
Along with this, I introduced the concept of "chains". Because an incremental
|
||||
backup describes the changes that occurred since the last backup, it needs that
|
||||
other backup in order to be fully restored. This also implies that the first
|
||||
incremental backup needs to be based off a full backup. A chain defines a list
|
||||
of sequential backups that all depend on the one before them, with each chain
|
||||
starting with a full backup.
|
||||
|
||||
All of this combined resulted in the following configuration for backups: the
|
||||
admin can configure one or more backup schedules, with each schedule being
|
||||
defined by a name, a frequency, a chain length and how many chains to keep. For
|
||||
each of these configurations, a new backup will be created periodically
|
||||
according to the defined frequency, and this backup will be appended to the
|
||||
current chain for that schedule. If the chain is full (as defined by the chain
|
||||
length), a new chain is created. Finally, the admin can configure how many of
|
||||
these full chains to keep.
|
||||
|
||||
As an example, my server currently uses a dual-schedule system:
|
||||
|
||||
* One configuration is called "30min". As the name suggests, it has a frequency
|
||||
of 30 minutes. It stores chains of length 48, and keeps 1 full chain. This
|
||||
configuration allows me to create incremental backups (which take 5-10
|
||||
seconds) every 30 minutes, and I can restore these backups in this 30-minute
|
||||
granularity up to 24 hours back.
|
||||
* The second configuration is called "daily", and this one simply creates a
|
||||
full backup (a chain length of 1) every 24 hours, with 7 chains being stored.
|
||||
This allows me to roll back a backup with a 24-hour granularity up to 7 days
|
||||
back.
|
||||
|
||||
This configuration would've never been possible without incremental backups, as
|
||||
the 30 minute backups would've simply taken too long otherwise. The required
|
||||
disk space would've also been rather unwieldy, as I'd rather not store 48
|
||||
multi-gigabyte backups per day. With the incremental backups system, each
|
||||
backup after the initial full backup is only a few megabytes!
|
||||
|
||||
Of course, a tool like this wouldn't be complete without some management
|
||||
utilities, so the Alex binary contains tools for restoring backups, exporting
|
||||
incremental backups as a new full backup, and unpacking a backup.
|
||||
|
||||
## What's next?
|
||||
|
||||
There's still some improvements I'd like to add to Alex itself, notably making
|
||||
Alex more aware of the server's internal state by parsing its logs, and making
|
||||
restoring backups possible without having to stop the Alex instance (this is
|
||||
rather cumbersome in Docker containers).
|
||||
|
||||
On a bigger scale however, there's another possible route to take: add a
|
||||
central server component where an Alex instance can publish its backups to.
|
||||
This server would then have a user management system to allow certain users of
|
||||
the Minecraft server to have access to the backups for offline use. This server
|
||||
could perhaps also show the logs of the server instance, as well as handling
|
||||
syncing the backups to another location, such as an S3 store. This would make
|
||||
the entire system more resistant to data loss.
|
||||
|
||||
Of course, I'm well aware these ideas are rather ambitious, but I'm excited to
|
||||
see where this project might go next!
|
||||
|
||||
That being said, Alex is available as statically compiled binaries for `amd64`
|
||||
and `arm64` [on my Gitea](https://git.rustybever.be/Chewing_Bever/alex). If
|
||||
you're interested in following the project, Gitea recently added repository
|
||||
[RSS feeds](https://git.rustybever.be/Chewing_Bever/alex.rss) ;)
|
||||
BIN
content/blog/alex/the-village.jpg
Normal file
BIN
content/blog/alex/the-village.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 593 KiB |
71
content/blog/audio-setup/index.md
Normal file
71
content/blog/audio-setup/index.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
title: "Audio Setup"
|
||||
date: 2022-08-16
|
||||
---
|
||||
|
||||
Over the years, I've invested in a (in my opinion) pretty good audio setup that
|
||||
I use very frequently (especially during the winter). I'm quite fond of it, so
|
||||
I'd like to show it off! And perhaps, someone out there might find the
|
||||
information interesting :)
|
||||
|
||||
# Hardware
|
||||
|
||||
The hardware consists of four main parts. I use a [Focusrite Scarlett
|
||||
2i2](https://focusrite.com/en/usb-audio-interface/scarlett/scarlett-2i2) both
|
||||
as a USB-connected DAC and an interface for my microphone. I'm quite satisified
|
||||
with the 2i2; it has served me well for a few years now. The fact that it can
|
||||
act both as a DAC and a mic input allows me to declutter my desk a bit.
|
||||
Otherwise, I'd have to buy a separate DAC and microphone receiver. Perhaps
|
||||
someday I'll find a use for the second microphone input ;p Before I had the
|
||||
2i2, I used a USB microphone and an AUX adapter that connected directly to my
|
||||
headphone amp, so this really was a big upgrade for me.
|
||||
|
||||
The 2i2's line outputs connect to a [Schiit Magni
|
||||
Heresy](https://www.schiit.com/products/magni-1); the headphone amplifier.
|
||||
Besides the glorious name, this product really is amazing. It packs a serious
|
||||
punch for its size and price and I find it's a great match for my headphones.
|
||||
The only issue that I've had with them is that they can crackle when you change
|
||||
the volume, but luckily it goes away again once you stop moving the knob.
|
||||
Personally, I don't think it's that much of an issue, but I figured I should
|
||||
mention it anyways.
|
||||
|
||||
Now for the stars of the show; the headphones. Perhaps I went a little
|
||||
overboard with this one, but I don't regret it at all. My main drivers are the
|
||||
[Sennheiser HD 660S](https://www.sennheiser-hearing.com/en-US/p/hd-660s/). They
|
||||
sound absolutely amazing paired with my Magni head amp. I'm by no means an
|
||||
expert on audio, but I can definitely tell a major difference between these
|
||||
headphones and any other pair we have in the house. The audio is incredibly
|
||||
clear; I really can't get enough of it.
|
||||
|
||||
Lastly, the microphone. During the pandemic, I bought myself a Devine BM-600
|
||||
XLR mic. The quality's quite good, especially for the price. Sadly I don't get
|
||||
to use it a lot anymore, as I rarely call people on the computer anymore.
|
||||
Before this however, I used the Devine M-Mic USB microphone. I mention this
|
||||
because it's probably one of the best budget microphones out there. Last I
|
||||
checked, it only cost around 30 euros and the voice quality is insanely good
|
||||
for the price.
|
||||
|
||||
# Software
|
||||
|
||||
While I get the appeal of LPs and CDs, they're just not very practical with the
|
||||
amount of music that I listen to every day. That's why I have a
|
||||
[Tidal](https://tidal.com/) HiFi subscription. Due to me being a student, I can
|
||||
get a 50% discount, meaning I only pay 5 euros per month for high-quality audio
|
||||
streaming. I highly recommend Tidal; it has served me well for months and will
|
||||
continue to do so.
|
||||
|
||||
Due to me using Linux, I sadly can't use a native Tidal client, so I've had to
|
||||
resort to using
|
||||
[Mastermindzh/tidal-hifi](https://github.com/Mastermindzh/tidal-hifi),
|
||||
specifically installed using the
|
||||
[tidal-hifi-git](https://aur.archlinux.org/packages?O=0&K=tidal-hifi-git) AUR
|
||||
package. It runs the Tidal web player in an electron session, along with some
|
||||
wine magic to support HiFi playback. It even has a task bar icon and
|
||||
everything, so it works about as well as any other native client.
|
||||
|
||||
Right, I have to finish this post. The goal was to describe my audio setup, and
|
||||
I think I accomplished that. I'm definitely not an expert on these things, so
|
||||
I'm not going to go more in depth than needed. All I am is an audiophile that
|
||||
cares a little too much about the quality of his music ;p
|
||||
|
||||
Cheers
|
||||
142
content/blog/c-project-setup/index.md
Normal file
142
content/blog/c-project-setup/index.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
---
|
||||
title: "My C Project Setup"
|
||||
date: 2024-03-28
|
||||
---
|
||||
|
||||
For the last couple of months most of my projects have revolved around
|
||||
low-level C programming, with the most prominent one being
|
||||
[Lander](https://git.rustybever.be/Chewing_Bever/lander), my URL shortener.
|
||||
During this time I've developed a method for structuring my repositories in a
|
||||
way that works for me and my development style. In this post, I'll be detailing
|
||||
my approach!
|
||||
|
||||
If you prefer looking at the structure directly, the basic structure's
|
||||
available as [a template](https://git.rustybever.be/Chewing_Bever/c-template)
|
||||
on my Gitea.
|
||||
|
||||
## Basic structure
|
||||
|
||||
The basic structure for my repositories looks like this:
|
||||
|
||||
```
|
||||
.
|
||||
├── example
|
||||
├── include
|
||||
│ └── project_name
|
||||
├── src
|
||||
│ ├── _include
|
||||
│ │ └── project_name
|
||||
│ └── project_name
|
||||
└── test
|
||||
```
|
||||
|
||||
Let's break it down.
|
||||
|
||||
Naturally, `src` contains the actual source files, both those native to the
|
||||
project and those included from thirdparty libraries. `src/project_name`
|
||||
contains all source files native to the project, while thirdparty files are
|
||||
stored in their own subdirectories separated by library, or directly in `src`.
|
||||
|
||||
For header files, we have two relevant directories. `include/project_name`
|
||||
contains all header files that are part of the public API for the library.
|
||||
`src/_include` on the other hand contains header files that are only used
|
||||
internally by the project. Here we once again have the same split where
|
||||
`src/_include/project_name` contains internal header files native to the
|
||||
project, while thirdparty header files can be placed either directly in
|
||||
`src/_include` or in their own subdirectories.
|
||||
|
||||
Finally we have `test` and `example`. `test` contains unit tests, while
|
||||
`example` contains source files that illustrate how to use the library in a
|
||||
practical context.
|
||||
|
||||
This setup seems to be fairly standard, and it works perfectly for me. To power
|
||||
a C project, we of course need some form of build system, so let's talk about
|
||||
*the Makefile*.
|
||||
|
||||
## The Makefile
|
||||
|
||||
During my years of creating personal projects I started leaning more towards a
|
||||
lightweight development style. For a while I was a big fan of CMake, but for my
|
||||
projects it's way too complex. As a replacement, I opted for a hand-written
|
||||
Makefile. While I'm not going to go into detail on the specifics of the
|
||||
[Makefile](https://git.rustybever.be/Chewing_Bever/c-template), I will mention
|
||||
its most predominant features.
|
||||
|
||||
First and foremost it supports compiling all required files and linking them
|
||||
into either a static library or a native binary, depending on the project. It
|
||||
allows all source files to include any header file from both `include` and
|
||||
`src/_include`. Unit tests and example binaries are compiled separately and
|
||||
linked with the static library. Unit tests are allowed to include any internal
|
||||
header file for more precise testing where needed, whereas example binaries
|
||||
only get access to the public API.
|
||||
|
||||
The Makefile properly utilizes the `CC`, `CFLAGS` and `LDFLAGS` variables,
|
||||
allowing me to build release binaries and libraries simply by running `make
|
||||
CFLAGS='-O3' LDFLAGS='-flto'`. Make also allows running compilation in parallel
|
||||
using the `-j` flag, greatly speeding up compilation. A properly written
|
||||
Makefile really does make life a lot easier.
|
||||
|
||||
It also solves a common issue with C compilation: header files. The usual
|
||||
bog-standard Makefile only defines the C source file as a dependency for its
|
||||
respective object file. Because to this, object files do not get recompiled
|
||||
whenever a header file included by its source file is changed. This can result
|
||||
in unexpected errors when linking. The Makefile solves this by setting the
|
||||
`-MMD -MP` compiler flags. `-MMD` tells the compiler to generate a Makefile in
|
||||
the build directory next to each source file's object file. These Makefiles
|
||||
define all included header files as a dependency for its respective object
|
||||
file. By importing these Makefiles into our main Makefile, our object files are
|
||||
automatically recompiled whenever a relevant header file is changed.
|
||||
|
||||
The Makefile also contains some quality-of-life phony targets for stuff I use
|
||||
regularly:
|
||||
|
||||
* `make lint` and `make fmt` use `clang-format` to lint and format the source
|
||||
files
|
||||
* `make check` runs `cppcheck` (and possibly other tools in the future) on the
|
||||
source code, notifying me of obvious memory leaks or mistakes
|
||||
* `make test` compiles all test binaries and runs the unit tests
|
||||
* `make run` compiles and runs the main binary
|
||||
* `make build-example` builds all examples
|
||||
* `make bear` generates a `compile_commands.json` file using
|
||||
[Bear](https://github.com/rizsotto/Bear) (the `clangd` LSP server requires
|
||||
this to work properly)
|
||||
* `make clean` removes all build artifacts
|
||||
|
||||
## Testing
|
||||
|
||||
My setup currently only supports unit tests, as I haven't really had the need
|
||||
for anything more complex. For this, I use
|
||||
[acutest](https://github.com/mity/acutest), a simple and easy to use
|
||||
header-only testing framework that's perfect for my projects. It's fully
|
||||
contained within a single header file that gets imported by all test files
|
||||
under the `test` directory. By having the testing framework fully contained in
|
||||
the project it also becomes very easy to run tests in a CI. If the CI
|
||||
environment can compile the library it can also run the tests without any
|
||||
additional dependencies required.
|
||||
|
||||
## Combining projects
|
||||
|
||||
My projects, specifically libraries, often start as part of a different project
|
||||
(e.g. [lnm](https://git.rustybever.be/Chewing_Bever/lnm) used to be part of
|
||||
[Lander](https://git.rustybever.be/Chewing_Bever/lander)). As the parent
|
||||
project grows, some sections start to grow into their own, self-contained unit.
|
||||
At this point, I take the time to properly decouple the codebases, moving the
|
||||
new library into its own subdirectory. This subdirectory then gets the same
|
||||
structure as described above, allowing the parent project to include it as a
|
||||
static library.
|
||||
|
||||
This approach gives me a lot of flexibility when it comes to testing, as well
|
||||
as giving me the freedom to separate subprojects into their own repositories as
|
||||
desired. Each project functions exactly the same if it's a local subdirectory
|
||||
or a Git submodule, allowing me to easily use my libraries in multiple projects
|
||||
simply by including them as submodules.
|
||||
|
||||
## Outro
|
||||
|
||||
That was my C project setup in a nutshell. Maybe this post could be of use to
|
||||
someone, giving them ideas on how to improve their existing setups.
|
||||
|
||||
As is standard with this blog, this post was rather technical. If you got to
|
||||
this point, thank you very much for reading.
|
||||
|
||||
Jef
|
||||
5
content/blog/endeavour-review/index.md
Normal file
5
content/blog/endeavour-review/index.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "A Review of EndeavourOS"
|
||||
date: 2022-04-05
|
||||
draft: true
|
||||
---
|
||||
60
content/blog/feeling-slightly-off/index.md
Normal file
60
content/blog/feeling-slightly-off/index.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
title: "Feeling Slightly Off"
|
||||
date: 2023-03-18
|
||||
---
|
||||
|
||||
This weekend's the first time in a couple of weeks that I've had a bit of
|
||||
breathing space. I've started to realize that I've been feeling a bit off. I've
|
||||
had a busy schedule this semester, lots of people to catch up with, and more
|
||||
uni work than I expected. Yesterday was the first climax of this, with two
|
||||
deadlines and a group presentation due. It became so busy I had to cancel a fun
|
||||
evening solely due to uni work.
|
||||
|
||||
These last couple of weeks, I've been going through life chasing my calendar,
|
||||
making sure I meet deadlines, while constantly remembering that I still have
|
||||
stuff to do in the evening. Don't get me wrong, I loved every social outing,
|
||||
but I'm aware that I tend to sacrifice a bit of myself sometimes to keep this
|
||||
schedule going. It's not the first time I've been stressed about going out, due
|
||||
to me planning too many things to do. I find myself coming home tired from
|
||||
studying and classes, taking a quick shower and chugging a Red Bull before
|
||||
going out again an hour later. I don't like saying no to outings, and I've
|
||||
always got some FOMO.
|
||||
|
||||
My sleep's been suffering, but more importantly, I've caught myself caring less
|
||||
about my health. When I come home for the weekend, I find myself answering "oh,
|
||||
I haven't checked it" when my dad asks whether my blood pressure and weight are
|
||||
still in check, and I haven't gone running in a week. After a while I started
|
||||
noticing this, and it's given me this slight feeling of dread, and perhaps a
|
||||
lack of control. I can be a bit paranoid about my health sometimes, and these
|
||||
habits kept that feeling in check, but now it's bubbling up ever so slightly.
|
||||
|
||||
Ever since I've had my appendix removed, I've been out of this rhythm I had
|
||||
created over the last year. Running was very much a key part of this routine,
|
||||
something that helped keep everything grounded. I knew that I went running
|
||||
every two days. It didn't feel like an obligation, but the idea of that rigid
|
||||
schedule helped me plan everything else. Because I wasn't able to exercise for
|
||||
a few weeks after the surgery (partially due to me being too paranoid about it
|
||||
all), I've lost this feeling of consistency, and I've been struggling to find
|
||||
it back. At this point, my body has fully healed and I'd be perfectly able to
|
||||
handle this rhythm again, but I just haven't found that same flow.
|
||||
|
||||
My food hasn't been too healthy either. I've eaten a lot of junk food, more
|
||||
than usual. Normally I don't mind this considering I partially compensated for
|
||||
this by running, but recently that argument hasn't worked, so I'm fearing that
|
||||
I'll start gaining weight again. On a brighter note, I've started prepping
|
||||
lunches for the week (partially due to uni restaurants being way too expensive
|
||||
nowadays), but I want to start pairing this habit with proper evening meals,
|
||||
instead of junk food 2-3 times a week.
|
||||
|
||||
All this has combined into a sense of fear, fear that it might come to bite me
|
||||
in the ass some day. I felt the need to write these thoughts down, to collect
|
||||
them properly in my head. On this Saturday, I felt the need to take control of
|
||||
my schedule again. Luckily I have some breathing room next week as I have no
|
||||
deadlines due, and I hope to use this time to start getting back into this
|
||||
rhythm.
|
||||
|
||||
As usual, I don't know how to end these posts, they're more of a dump of
|
||||
thoughts than anything else. I'm well aware this post could come off as
|
||||
pretentious. I'm basically complaining about having too many things to do while
|
||||
having shitty time management, and that's fine. After all, I'm collecting *my*
|
||||
thoughts. Thanks for reading.
|
||||
138
content/blog/lander/index.md
Normal file
138
content/blog/lander/index.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
---
|
||||
title: "Designing my own URL shortener"
|
||||
date: 2023-10-14
|
||||
---
|
||||
|
||||
One of the projects I've always found to be a good choice for a side project is
|
||||
a URL shortener. The core idea is simple and fairly easily to implement, yet it
|
||||
allows for a lot of creativity in how you implement it. Once you're done with
|
||||
the core idea, you can start expanding the project as you wish: expiring links,
|
||||
password protection, or perhaps a management API. The possibilities are
|
||||
endless!
|
||||
|
||||
Naturally, this post talks about my own version of a URL shortener:
|
||||
[Lander](https://git.rustybever.be/Chewing_Bever/lander). In order to add some
|
||||
extra challenge to the project, I've chosen to write it from the ground up in C
|
||||
by implementing my own event loop, and building an HTTP server on top to use as
|
||||
the base for the URL shortener.
|
||||
|
||||
## The event loop
|
||||
|
||||
Lander consists of three layers: the event loop, the HTTP loop and finally the
|
||||
Lander-specific code. Each of these layers utilizes the layer below it, with
|
||||
the event loop being the bottom-most layer. This layer directly interacts with
|
||||
the networking stack and ensures bytes are received from and written to the
|
||||
client. The book [Build Your Own Redis](https://build-your-own.org/redis/) by
|
||||
James Smith was an excellent starting point, and I highly recommend checking it
|
||||
out! This book taught me everything I needed to know to start this project.
|
||||
|
||||
Now for a slightly more techical dive into the inner workings of the event
|
||||
loop. The event loop is the layer that listens on the listening TCP socket for
|
||||
incoming connections and directly processes requests. In each iteration of the
|
||||
event loop, the following steps are taken:
|
||||
|
||||
1. For each of the open connections:
|
||||
1. Perform network I/O
|
||||
2. Execute data processing code, provided by the upper layers
|
||||
3. Close finished connections
|
||||
2. Accept a new connection if needed
|
||||
|
||||
The event loop runs on a single thread, and constantly goes through this cycle
|
||||
to process requests. Here, the "data processing code" is a set of function
|
||||
pointers passed to the event loop that get executed at specific times. This is
|
||||
how the HTTP loop is able to inject its functionality into the event loop.
|
||||
|
||||
In the event loop, a connection can be in one of three states: `request`,
|
||||
`response`, or `end`. In `request` mode, the event loop tries to read incoming
|
||||
data from the client into the read buffer. This read buffer is then used by the
|
||||
data processing code's data handler. In `response` mode, the data processing
|
||||
code's data writer is called, which populates the write buffer. This buffer is
|
||||
then written to the connection socket. Finally, the `end` state simply tells
|
||||
the event loop that the connection should be closed without any further
|
||||
processing. A connection can switch between `request` and `response` mode as
|
||||
many times as needed, allowing connections to be reused for multiple requests
|
||||
from the same client.
|
||||
|
||||
The event loop provides all the necessary building blocks needed to build a
|
||||
client-server type application. These are then used to implement the next
|
||||
layer: the HTTP loop.
|
||||
|
||||
## The HTTP loop
|
||||
|
||||
Before we can design a specific HTTP-based application, we need a base to build
|
||||
on. This base is the HTTP loop. It handles both serializing and deserializing
|
||||
of HTTP requests & responses, along with providing commonly used functionality,
|
||||
such as bearer authentication and reading & writing files to & from disk. The
|
||||
request parser is provided by the excellent
|
||||
[picohttpparser](https://github.com/h2o/picohttpparser) library. The parsed
|
||||
request is stored in the request's data struct, providing access to this data
|
||||
for all necessary functions.
|
||||
|
||||
The HTTP loop defines a request handler function which is passed to the event
|
||||
loop as the data handler. This function first tries to parse the request,
|
||||
before routing it accordingly. For routing, literal string matches or
|
||||
RegEx-based routing is available.
|
||||
|
||||
Each route consists of one or more steps. Each of these steps is a function
|
||||
that tries to advance the processing of the current request. The return value
|
||||
of these steps tells the HTTP loop whether the step has finished its task or if
|
||||
it's still waiting for I/O. The latter instructs the HTTP loop to skip this
|
||||
request for now, delaying its processing until the next cycle of the HTTP loop.
|
||||
In each cycle of the HTTP loop (or rather, the event loop), a request will try
|
||||
to advance its processing by as much as possible by executing as many steps as
|
||||
possible, in order. This means that very small requests can be completely
|
||||
processed within a single cycle of the HTTP loop. Common functionality is
|
||||
provided as predefined steps. One example is the `http_loop_step_body_to_buf`
|
||||
step, which reads the request body into a buffer.
|
||||
|
||||
The HTTP loop also provides the data writer functionality, which will stream an
|
||||
HTTP response to the write buffer. The contents of the response are tracked in
|
||||
the request's data struct, and these data structs are recycled between requests
|
||||
using the same connection, preventing unnecessary allocations.
|
||||
|
||||
## Lander
|
||||
|
||||
Above the HTTP loop layer, we finally reach the code specific to Lander. It
|
||||
might not surprise you that this layer is the smallest of the three, as the
|
||||
abstractions below allow it to focus on the task at hand: serving and storing
|
||||
HTTP redirects (and pastes). The way these are stored however is, in my
|
||||
opinion, rather interesting.
|
||||
|
||||
For our Algorithms & Datastructures 3 course, we had to design three different
|
||||
trie implementations in C: a Patricia trie, a ternary trie and a "custom" trie,
|
||||
where we were allowed to experiment with different ideas. For those unfamiliar,
|
||||
a trie is a tree-like datastructure used for storing strings. The keys used in
|
||||
this tree are the strings themselves, with each character causing the tree to
|
||||
branch off. Each string is stored at depth `m`, with `m` being the length of
|
||||
the string. This also means that the search depth of a string is not bounded by
|
||||
the size of the trie, but rather the size of the string! This allows for
|
||||
extremely fast lookup times for short keys, even if we have a large number of
|
||||
entries.
|
||||
|
||||
My design ended up being a combination of both a Patricia and a ternary trie: a
|
||||
ternary trie that supports skips the way a Patricia trie does. I ended up
|
||||
taking this final design and modifying it for this project by optimising it (or
|
||||
at least try to) for shorter keys. This trie structure is stored completely in
|
||||
memory, allowing for very low response times for redirects. Pastes are served
|
||||
from disk, but their lookup is also performed using the same in-memory trie.
|
||||
|
||||
## What's next?
|
||||
|
||||
Hopefully the above explanation provides some insight into the inner workings
|
||||
of Lander. For those interested, the source code is of course available
|
||||
[here](https://git.rustybever.be/Chewing_Bever/lander). I'm not quite done with
|
||||
this project though.
|
||||
|
||||
My current vision is to have Lander be my personal URL shortener, pastebin &
|
||||
file-sharing service. Considering a pastebin is basically a file-sharing
|
||||
service for text files specifically, I'd like to combine these into a single
|
||||
concept. The goal is to rework the storage system to support arbitrarily large
|
||||
files, and to allow storing generic metadata for each entry. The initial
|
||||
usecase for this metadata would be storing the content type for uploaded files,
|
||||
allowing this header to be correctly served when retrieving the files. This
|
||||
combined with supporting large files turns Lander into a WeTransfer
|
||||
alternative! Besides this, password protection and expiration of pastes is on
|
||||
my to-do list as well. The data structure currently doesn't support removing
|
||||
elements either, so this would need to be added in order to support expiration.
|
||||
|
||||
Hopefully a follow-up post announcing these changes will come soon ;)
|
||||
49
content/blog/losing-weight/index.md
Normal file
49
content/blog/losing-weight/index.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
title: "I've lost weight!"
|
||||
date: 2022-07-10
|
||||
---
|
||||
|
||||
Ever since I started middle school, I've been a bit of a chubby kid. I was
|
||||
never into sports & honestly I just like food. The fact that my main hobby,
|
||||
computer stuff, requires me to sit down all the time doesn't help my case
|
||||
either.
|
||||
|
||||
My health was never really a big concern for me, as I generally felt pretty
|
||||
good physically. A few months ago however, I finally found the courage to go
|
||||
donate blood (I absolutely despise needles)! Whenever you want to donate blood
|
||||
(at least, here in Belgium) they check your blood pressure to make sure you're
|
||||
allowed to give blood, and that's when I found out that my blood pressure was
|
||||
apparently way too high. This was a big eye-opener for me, as it was the first
|
||||
time I was being confronted with a consequence of my weight and just general
|
||||
lack of self-care.
|
||||
|
||||
Shortly after, I made an appointment with a doctor, who then referred me to a
|
||||
cardiologist, who then once again told me that my blood pressure is indeed way
|
||||
too high. Due to my young age however, they were hesitant to prescribe me
|
||||
medication and instead encouraged me to start exercising more to see if this
|
||||
helped the problem.
|
||||
|
||||
Suffice to say, my health has notably improved ever since I changed my
|
||||
lifestyle! I've started running regularly (and have been enjoying it
|
||||
surprisingely) and lowered my portion size when eating. For the first couple of
|
||||
weeks, I was constantly hungry, but afterwards my stomach adjusted. Nowadays,
|
||||
I'm already full after a portion half the size of before!
|
||||
|
||||
This post has been in the back of my mind for a while, but I wanted to wait
|
||||
until I hit a specific milestone. When I started losing weight, I weighed
|
||||
around 111kg, but a few days ago I weighed less than a hundred kilos for the
|
||||
first time in years! My weight definitely ballooned when I started university,
|
||||
so it felt really good to see that 99.9 on the scale. My blood pressure has
|
||||
also notably improved, thanks to the weight loss and exercise.
|
||||
|
||||
Of course I'm not going to stop now, but this was a specific goal that I had in
|
||||
mind to motivate myself to keep going. My friends and family have been
|
||||
commenting on my weight loss, and it's really nice to hear people say that I
|
||||
lost weight for a change. I am grateful that this was discovered so soon. Being
|
||||
only twenty-one, I'm still more than capable of becoming healthier. I'd rather
|
||||
exercise now than deal with the possible implications from high blood pressure
|
||||
years down the road.
|
||||
|
||||
As usual, I have no idea how to end these posts; I just wanted to share my
|
||||
accomplishment, as I'm quite proud of it :) Anyways, if you've gotten this far,
|
||||
thank for you reading and have a very nice day <3
|
||||
58
content/blog/music/index.md
Normal file
58
content/blog/music/index.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
title: "Music"
|
||||
date: 2022-05-16T20:58:18+02:00
|
||||
---
|
||||
|
||||
Music has a profound effect on me. It dictates my mood, helps me process
|
||||
emotions or keeps me focused. It motivates me when I'm running & helps me when
|
||||
I'm down. And of course, I'm listening to some great music while writing this
|
||||
post.
|
||||
|
||||
I felt like writing, mostly because I was feeling a bit like shit. It calms me
|
||||
down, helps me put things in order. The idea to write about music just popped
|
||||
into my head, but I've had it in the back of mind for a while now.
|
||||
|
||||
Music really is something special. It can evoke such a wide range of emotions,
|
||||
from blissful joy to a depressed pitfall & everything in between. Whenever I'm
|
||||
feeling down I just crack up some tunes. Not necessarily happy tunes mind you,
|
||||
sometimes it's better to soak in the sadness for a bit, there's no point in
|
||||
keeping it inside.
|
||||
|
||||
According to most people's standards, I listen to music *a lot*. I put in my
|
||||
earbuds when I leave for classes at 8AM, or put on my headphones when I'm
|
||||
working behind my desk. Every time I ride my bike, walk or run, I'm listening
|
||||
to music. Whenever I'm studying or programming, I'm listening to music. In
|
||||
total, I probably listen to music for at least 6 hours a day. Luckily that is
|
||||
more than enough to justify buying a Tidal subscription for 10 euros a month ;p
|
||||
|
||||
That does bring me to my next point; I'm an audiophile. I love high resolution
|
||||
audio & my audio setup reflects that. My Sennheiser HD 660S are very dear to
|
||||
me, and they've provided me with hundreds of hours of listening pleasure at
|
||||
this point.
|
||||
|
||||
I'm not really picky with what genres of music I listen to either. The music
|
||||
just has to provide a certain feeling that fits my current mood. I do prefer
|
||||
listening to entire albums, which is why I've amassed a great list of albums
|
||||
that I love to listen to. Despite my horrible memory I tend to navigate this
|
||||
list just fine, with each song just coming up as a feeling in the moment & my
|
||||
mind magically navigating to the right album.
|
||||
|
||||
My love for music has been around for as long as I can remember. Back in high
|
||||
school I was constantly listening to music; I've even played the piano for
|
||||
years before stopping due to a lack of interest. Sadly that spirals back to my
|
||||
lack of motivation for most things, but I digress.
|
||||
|
||||
The truth is, I wanted to write, just write, to process the exam stress that
|
||||
I'm going through right now. I've got exams in two weeks & as usual, the stress
|
||||
has been killing me. My horrible sleep hygiene doesn't help either. I rarely go
|
||||
to bed before midnight & when I do, I just lie awake in bed, thinking. Thinking
|
||||
of how I'll have to study more tomorrow, because otherwise I won't make it. A
|
||||
constant fear of failure looms above me, ready to eat me up inside.
|
||||
|
||||
Well, this post got depressing quite fast, I'm sorry about that. Thing is, I
|
||||
want to use this site to express myself, so when I'm feeling stressed, I want
|
||||
to express that as well. It's liberating in a way, sharing this information
|
||||
with "the world", in my own controlled way.
|
||||
|
||||
If you've gotten this far, thank for you reading through my ramblings &
|
||||
insecurities, I do truly appreciate it. Au revoir.
|
||||
50
content/blog/necessity/index.md
Normal file
50
content/blog/necessity/index.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
title: "Necessity Creates Productivity"
|
||||
date: 2022-04-07T09:46:05+02:00
|
||||
---
|
||||
|
||||
Or at least, that's how I experience it. Let me explain.
|
||||
|
||||
I have a lot of sideprojects. Most would say too many (I'm inclined to agree).
|
||||
I often start these projects because I feel like it, without a particular
|
||||
purpose or useful goal in mind. Programming is just something that I really
|
||||
enjoy, so I tend to create ideas out of thin air just because I want to write
|
||||
something, anything. There is however another group of sideprojects, the ones
|
||||
that I start because I need something. Those that fix an annoyance, or make my
|
||||
life easier. What I've noticed is that I'm a lot more productive & less easily
|
||||
burned out when I'm working on these kinds of projects.
|
||||
|
||||
One of those projects (and my main project atm) is
|
||||
[Vieter](https://git.rustybever.be/Chewing_Bever/vieter). I originally wrote a
|
||||
full description of Vieter here & why I needed it, but that's really not what
|
||||
this post is about. You can still read about it in [the docs](/docs/vieter/#why)
|
||||
if you want. The important part to take away from this is that it's something I
|
||||
really need. It made me more productive and greatly pushed down my update
|
||||
times, which I personally find very important. That's why I'm getting a lot of
|
||||
things done for this project, because I know that it'll be worth it in the end
|
||||
& improve my life.
|
||||
|
||||
To show the other site of the spectrum, my original idea for this site was a
|
||||
collection of microservices, with a complex authentication system & a full
|
||||
JavaScript frontend ([source](https://git.rustybever.be/rusty-bever)). Let's
|
||||
just admit it here, this idea was way too ambitious and not even *that* useful.
|
||||
The only part that I'm actually still considering writing is the authentication
|
||||
part, because I do have some other ideas to go along with those, but that's
|
||||
another post entirely ;p
|
||||
|
||||
Due to this overkill idea, I didn't actually set up this site for over a year I
|
||||
think, just because I just couldn't get myself to properly work on the
|
||||
implementation. I actually really enjoy writing these blog-style posts, so it's
|
||||
quite sad I didn't set up a proper Hugo-based site immediately. Gladly at some
|
||||
point I got through my stubbornness, and I set up this site in less than a day
|
||||
:) This site still runs on [a custom backend](/switch-to-axum), but it's much
|
||||
more minimal and only supports what I really need. My mind's a lot calmer now
|
||||
that I've properly left my original idea behind.
|
||||
|
||||
I'm honestly not quite sure what point I'm trying to make. This post is just an
|
||||
observation about how my unpredictable mind can work. Knowing myself, the
|
||||
sideprojects will probably never stop coming, but that's okay tbh. The
|
||||
important part is that most of them have a purpose, and don't just burn me out
|
||||
unnecessarily.
|
||||
|
||||
Fin.
|
||||
42
content/blog/switch-to-axum.md
Normal file
42
content/blog/switch-to-axum.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
title: "Switching to Axum"
|
||||
date: 2022-04-02
|
||||
tags:
|
||||
- rust
|
||||
---
|
||||
|
||||
In classic Jef fashion, it took me less than a week to completely overhaul the
|
||||
way my site works ;p Visually nothing's changed, but internally the website is
|
||||
now being powered by a web server [written in
|
||||
Rust](https://git.rustybever.be/Chewing_Bever/site-backend), powered by
|
||||
[Axum](https://github.com/tokio-rs/axum).
|
||||
|
||||
The reason for this is expandibility. While nginx is really good at what it
|
||||
does, it's rather limited when it comes to implementing new features on top of
|
||||
it. However, even if it wasn't, I would've still switched because I just really
|
||||
wanted to work in Rust once more :D
|
||||
|
||||
Favoritism aside, the plan is to join the [IndieWeb](https://indieweb.org/)
|
||||
network. To quote their homepage:
|
||||
|
||||
> The IndieWeb is a people-focused alternative to the "corporate web".
|
||||
|
||||
They've got some really great ideas about what the internet could be if we
|
||||
tried, and considering I agree with nearly all of them, I wanna join ;p
|
||||
|
||||
My first project will be to implement the Webmention protocol. This consists of
|
||||
a simple exchange of POST requests, where you notify another user's site
|
||||
whenever you mention one of their posts. This in exchange allows them to
|
||||
display my response on their website, and vice versa! In essence, it's simple
|
||||
decentralized commenting.
|
||||
|
||||
My plans after this are still vague. I might dip my toes into
|
||||
[IndieAuth](https://indieauth.net/),
|
||||
[microformats](https://indieweb.org/microformats) or any of the other cool
|
||||
concepts they've got the offer! Either way, the plan is to enjoy myself with
|
||||
this site ;p
|
||||
|
||||
If all goes well, this post will be the first new post to get published using
|
||||
my new deploy system, so fingers crossed :)
|
||||
|
||||
Have a lovely day <3
|
||||
BIN
content/blog/tour-of-flanders/bert-enjoying-himself.jpg
Normal file
BIN
content/blog/tour-of-flanders/bert-enjoying-himself.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
26
content/blog/tour-of-flanders/index.md
Normal file
26
content/blog/tour-of-flanders/index.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
title: "Tour of Flanders"
|
||||
date: 2022-04-04T12:53:23+02:00
|
||||
---
|
||||
|
||||
Yesterday, some friends & I met to "watch" the Tour of Flanders (gonna have to
|
||||
trust Google Translate on this one). Mind the quotes, because none of us really
|
||||
know anything about cycling ;p One of us just lived close to where the tour
|
||||
ended, so we used this as an excuse to organize a party at their place!
|
||||
|
||||
It was really fun standing in a big crowd of bystanders while the two
|
||||
frontrunners passed by. Everyone went wild! It really shows how cosy a group of
|
||||
Belgians can be if we just don't talk about anything besides sports (let's
|
||||
leave the politics aside).
|
||||
|
||||
Afterwards, we went back to their place, ate some delicious burgers courtesy of
|
||||
their mom, and watched [De
|
||||
Mol](https://en.wikipedia.org/wiki/De_Mol_(TV_series)) together. For the rest
|
||||
of the evening we had some beer & wine (and a glass of Johnnie Walker Black
|
||||
Label ;) ), and just talked about everything. I really enjoy these kinds of
|
||||
evenings, chilling with friends, no pressure to go out, just relaxing & talking
|
||||
with some good booze :)
|
||||
|
||||
{{< figure src="./bert-enjoying-himself.jpg" title="Bert having some fun while we're all focused on the big screen" >}}
|
||||
|
||||
{{< figure src="./later-in-the-evening.jpg" title="After a few drinks (I gotta shave)" >}}
|
||||
BIN
content/blog/tour-of-flanders/later-in-the-evening.jpg
Normal file
BIN
content/blog/tour-of-flanders/later-in-the-evening.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
44
content/blog/tuxedo-book-xp14-review.md
Normal file
44
content/blog/tuxedo-book-xp14-review.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
title: "Tuxedo Book XP14 12th Gen Review"
|
||||
date: 2022-04-02
|
||||
draft: true
|
||||
---
|
||||
|
||||
Fro the last couple of years, my main driver was a Macbook Air 13" from 2013.
|
||||
It was my sister's old laptop & I claimed it when she replaced it because it
|
||||
became too slow. Naturally, I put Linux on it and, after a few distro hops,
|
||||
settled on EndeavourOS. This setup worked well for about 3 years, but it was
|
||||
getting rather old. After about a year of using it myself I had to replace the
|
||||
battery, and after another two years or so that one became useless as well. It
|
||||
was time for a change, so I started searching.
|
||||
|
||||
Thanks to a recommendation from a friend, I found Tuxedo Computers and I just
|
||||
couldn't get them out of my head, so eventually I gave in and bought one! As
|
||||
the title already revealed, the model's a Tuxedo Book XP14 Gen12.
|
||||
|
||||
My specific version has a 120Hz display, 500GB of a Samsung 980, 2 x 8GB of
|
||||
DDR4 RAM, an i5-1135G7 & Intel Iris Xe Graphics G7 80EUs.
|
||||
|
||||
Now that we've got the nerd stats out of the way, let's talk about the laptop
|
||||
itself.
|
||||
|
||||
## The Good
|
||||
|
||||
The build quality is very solid. While the top half containing the display is
|
||||
made up of a solid metal casing, the bottom part consists of a sturdy plastic.
|
||||
There is some deck flex, but definitely not a level I would consider an issue.
|
||||
|
||||
The trackpad is very responsive & pairs nicely with the smoothness of the
|
||||
cursor on the 120Hz display. I personally think the keyboard is quite amazing.
|
||||
It's got a satisfying travel time & feels very solid for a membrane keyboard.
|
||||
|
||||
IO is more than enough, with a Kensington lock, SD card reader, gigabit
|
||||
Ethernet port, Thunderbolt 4 port, two USB 3 ports, another USB-C port, HDMI &
|
||||
two-in-one audio jack.
|
||||
|
||||
Under normal load the fans are completely silent, while at peak they're audible
|
||||
but not annoying or overly loud.
|
||||
|
||||
Battery life is quite decent; under light load with dimmed backlight it can go
|
||||
for about 6 hours. I do recommend properly configuring some energy profiles in
|
||||
the Tuxedo Control Center.
|
||||
83
content/blog/v-workflow/index.md
Normal file
83
content/blog/v-workflow/index.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
title: "My V Workflow"
|
||||
date: 2022-04-27T22:13:04+02:00
|
||||
---
|
||||
|
||||
While I'm trying to find time to work on
|
||||
[Vieter](https://git.rustybever.be/Chewing_Bever/vieter) (college is killing me
|
||||
right now), I figured I could describe my current workflow for developing
|
||||
Vieter, and in general, V!
|
||||
|
||||
I've always been a rather minimal developer, preferring simplicity &
|
||||
lightweight programs over lots of smart IDE features. While this mentality
|
||||
doesn't work for all languages, V's simplicity allows me to write it without
|
||||
any smart features whatsoever!
|
||||
|
||||
## Tools
|
||||
|
||||
### Neovim
|
||||
|
||||
We can't do any coding without a text editor of course. My weapon of choice is
|
||||
[Neovim](https://neovim.io/), the great Vim fork, ran inside my [st
|
||||
build](https://git.rustybever.be/Chewing_Bever/st). My main reason for choosing
|
||||
Neovim over Vim (besides the more active development) is the Lua, LSP &
|
||||
Treesitter support.
|
||||
|
||||
I try to keep [my
|
||||
config](https://git.rustybever.be/Chewing_Bever/dotfiles/src/branch/master/.config/nvim)
|
||||
& list of plugins rather short by following the basic rule of only adding a
|
||||
plugin if I find it adds actual value to my setup. If the plugin or setting
|
||||
only adds a gimmick that I don't actively use, I probably won't add it.
|
||||
|
||||
### VLS
|
||||
|
||||
Thanks to the LSP support in Neovim I'm able to use
|
||||
[VLS](https://github.com/vlang/vls) (V Language Server). This gives me better
|
||||
autocomplete, useful suggestions & error messages, all without ever having to
|
||||
run the compiler myself!
|
||||
|
||||
### Treesitter
|
||||
|
||||
The VLS repo also comes with grammar definitions for treesitter. This allows me
|
||||
to import this into Neovim, providing me with better code highlighting using my
|
||||
treesitter-compatible theme.
|
||||
|
||||
### Compiler mirror
|
||||
|
||||
I don't like it when things break without my permission. While it's a very good
|
||||
thing that V is so actively developed, it does make programs rather sensitive
|
||||
to change & can cause stuff to break after a compiler update. This is why I
|
||||
maintain my own mirror of the compiler which I update regularly. Thanks to
|
||||
this, I have full control over how frequently my compiler updates, providing me
|
||||
with a level of stability on both my laptops & in my CI that can't be obtained
|
||||
when blindly following the master branch.
|
||||
|
||||
### Packaging for Arch Linux
|
||||
|
||||
My distro of choice for all my devices is EndeavourOS, an Arch-based distro
|
||||
(well, it's basically just a very good installer ;p). Thanks to this
|
||||
uniformity, it's very easy for me to package my compiler mirror, VLS & the
|
||||
treesitter grammar.
|
||||
|
||||
For the compiler, I build packages inside my CI
|
||||
([PKGBUILD](https://git.rustybever.be/Chewing_Bever/v/src/branch/master/PKGBUILD))
|
||||
& publish this package to my personal Vieter instance. Then, using this
|
||||
compiler package, I periodically build & package VLS
|
||||
([PKGBUILD](https://git.rustybever.be/bur/vieter-vls/src/branch/main/PKGBUILD)).
|
||||
This is to make sure my VLS build is compatible with my compiler version. The
|
||||
PKGBUILD also shows how to compile the treesitter grammar separately from VLS.
|
||||
|
||||
## Workflow
|
||||
|
||||
Just like my config, my way of working is rather simple. I really like working
|
||||
in the terminal, so I usually write small Makefiles
|
||||
([example](https://git.rustybever.be/Chewing_Bever/vieter/src/branch/dev/Makefile))
|
||||
that do everything I need, e.g. compile, lint, test etc. Using the
|
||||
[toggleterm](https://github.com/akinsho/toggleterm.nvim) plugin, I spawn
|
||||
terminals inside Neovim & use `make` to do everything else!
|
||||
|
||||
## Outro
|
||||
|
||||
I'm not too sure how to end this post. I hope it might help someone who's
|
||||
struggling to find a setup that works, or perhaps the links to my PKGBUILDs
|
||||
could come in handy for someone ;p
|
||||
29
content/blog/vieter-0.2.0/index.md
Normal file
29
content/blog/vieter-0.2.0/index.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
title: "Announcing Vieter 0.2.0"
|
||||
date: 2022-04-11
|
||||
---
|
||||
|
||||
When this post gets published, I'll have successfully released version 0.2.0 of
|
||||
[Vieter](https://git.rustybever.be/Chewing_Bever/vieter)! For the uninitiated,
|
||||
Vieter is currently my biggest passion project. It's an implementation of an
|
||||
Arch repository server, paired with a build system for automatically building
|
||||
packages from the AUR & other sources.
|
||||
|
||||
This release brings a lot of goodies; the changelog & release binaries can be
|
||||
found
|
||||
[here](https://git.rustybever.be/Chewing_Bever/vieter/releases/tag/0.2.0). The
|
||||
biggest changes are that Vieter now supports multiple repositories with support
|
||||
for packages for multiple architectures! Besides that, there's some bug fixing,
|
||||
improvements to the CLI & an added setting for the build system that allows for
|
||||
building on other architectures. The [docs](https://rustybever.be/docs/vieter/)
|
||||
have also been updated to reflect this new update.
|
||||
|
||||
Of course, development won't just stop now, I have too many ideas for that ;p
|
||||
[0.3.0](https://git.rustybever.be/Chewing_Bever/vieter/milestone/27) will bring
|
||||
with it some big improvements to the builder system, allowing for more
|
||||
flexibility & configuration.
|
||||
|
||||
If you're interested in the project, join me over at
|
||||
[#vieter:rustybever.be](https://matrix.to/#/#vieter:rustybever.be) on Matrix!
|
||||
|
||||
Cheers <3
|
||||
69
content/blog/vieter-0.3.0/index.md
Normal file
69
content/blog/vieter-0.3.0/index.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
title: "Announcing Vieter 0.3.0"
|
||||
date: 2022-06-13
|
||||
---
|
||||
|
||||
When this post is live, Vieter 0.3.0 will have been released! This release
|
||||
really does come with a lot of new features, including more reliable builds and
|
||||
a new cron implementation!
|
||||
|
||||
This release ended up taking me over two months, but I'm quite proud of it :)
|
||||
It not only adds a lot of useful features, but also paves the way for a lot
|
||||
more cool features down the road!
|
||||
|
||||
## What is Vieter?
|
||||
|
||||
Vieter consists of two independents parts, namely an implementation of an Arch
|
||||
(Pacman) repository, & a build system to populate said repository. The goal is
|
||||
to remove the need for an AUR helper & move all builds to a remote server. Not
|
||||
only does this greatly reduce update times on lower-end systems, it also
|
||||
prevents AUR packages from being built multiple times on different systems.
|
||||
|
||||
The repository can also be used independently, providing a convenient server
|
||||
for publishing Arch packages from CI builds for example.
|
||||
|
||||
While I specifically mention Arch & the AUR, Vieter is compatible with any
|
||||
Pacman-based distro & can build PKGBUILDs provided from any Git source.
|
||||
|
||||
## What's changed?
|
||||
|
||||
### New cron daemon
|
||||
|
||||
Perhaps the most important feature in this release is the implementation of a
|
||||
cron daemon. While 0.2.0 still relied on crond to periodically start builds,
|
||||
0.3.0 can schedule builds completely independently.
|
||||
|
||||
The daemon understands a subset of the cron expression syntax. The build
|
||||
schedule can be either configured globally or on a per-repo basis. This allows
|
||||
the user to fine-tune certain packages, e.g. if they want them to be updated
|
||||
more regularly than all the rest.
|
||||
|
||||
### More robust builds
|
||||
|
||||
Often, a build would fail with exit code 8. This error indicates that makepkg
|
||||
wasn't able to install all dependencies, caused by the builder image not being
|
||||
up to date enough. Due to this, each build now runs `pacman -Syu` before
|
||||
running the actual build.
|
||||
|
||||
Builds can now also use dependencies that are part of the target repository.
|
||||
This allows building packages with AUR dependencies, as long as all
|
||||
dependencies are also being built for said repository.
|
||||
|
||||
### Build logs
|
||||
|
||||
The main server now stores the logs of each build, including the exit code.
|
||||
This makes it a lot easier to debug why builds fail.
|
||||
|
||||
### Improved documentation
|
||||
|
||||
The [Vieter documentation](https://rustybever.be/docs/vieter/) has had a pretty
|
||||
major re-write to get it up to date with this new release. Now there's also
|
||||
[HTTP API docs](https://rustybever.be/docs/vieter/api/#introduction) & [man
|
||||
pages](https://rustybever.be/man/vieter/vieter.1.html).
|
||||
|
||||
## Interested?
|
||||
|
||||
If you're interested in Vieter, considering joining
|
||||
[#vieter:rustybever.be](https://matrix.to/#/#vieter:rustybever.be) on Matrix!
|
||||
The source code can be found on my personal
|
||||
[Gitea](https://git.rustybever.be/vieter/vieter).
|
||||
69
content/blog/vieter-0.4.0/index.md
Normal file
69
content/blog/vieter-0.4.0/index.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
title: "Announcing Vieter 0.4.0"
|
||||
date: 2022-10-01
|
||||
---
|
||||
|
||||
Right at the start of October, I managed to release another version of Vieter!
|
||||
|
||||
## What is Vieter?
|
||||
|
||||
Vieter consists of two independents parts, namely an implementation of an Arch
|
||||
(Pacman) repository, & a build system to populate said repository. The goal is
|
||||
to remove the need for an AUR helper & move all builds to a remote server. Not
|
||||
only does this greatly reduce update times on lower-end systems, it also
|
||||
prevents AUR packages from being built multiple times on different systems.
|
||||
|
||||
The repository can also be used independently, providing a convenient server
|
||||
for publishing Arch packages from CI builds for example.
|
||||
|
||||
While I specifically mention Arch & the AUR, Vieter is compatible with any
|
||||
Pacman-based distro & can build PKGBUILDs provided from any Git source.
|
||||
|
||||
## What's changed?
|
||||
|
||||
### Renaming `repos` to `targets`
|
||||
|
||||
Before 0.4.0, "repos" was the term used to describe the list of Git
|
||||
repositories that periodically get built on your Vieter instance. This term
|
||||
however was rather confusing, as the Vieter server itself also hosts Pacman
|
||||
repositories, making it difficult to correctly talk about the features. That's
|
||||
why I've made the decision to rename this to "targets". All CLI commands
|
||||
previously found under `vieter repos` can now be used via `vieter targets`
|
||||
instead. API routes have also been renamed.
|
||||
|
||||
Along with this, a new kind of target can now be added which specifies the link
|
||||
to a PKGBUILD file, instead of a Git repository. This can for example be used
|
||||
to link a PKGBUILD that's contained inside some other Git repository that's not
|
||||
specifically used for that PKGBUILD.
|
||||
|
||||
### Refactored web framework
|
||||
|
||||
The underlying web framework has seen a proper refactor to better accomodate
|
||||
the rest of the codebase. All API routes can now be found under a versioned
|
||||
`/api/v1` prefix.
|
||||
|
||||
The repository endpoints now support `DELETE` requests to remove packages,
|
||||
arch-repos & repos. All routes serving files (e.g. the repository routes) now
|
||||
support HTTP byte range requests, which not only allows Pacman to resume
|
||||
downloads after failure, but also allows tools such as
|
||||
[`axel`](https://github.com/axel-download-accelerator/axel) to work properly
|
||||
using a Vieter server.
|
||||
|
||||
Endpoints creating new entries on the server now return the ID of the newly
|
||||
created object (e.g. a target or a build log).
|
||||
|
||||
### CLI UX
|
||||
|
||||
The CLI has seen some useful changes. There's now a `-r` flag that makes
|
||||
Vieter's output better for scripting. Besides that, a small tool has been added
|
||||
to interact with the AUR and add AUR packages directly to your list of targets!
|
||||
|
||||
`vieter targets add` and `vieter logs add` now return the ID of the newly
|
||||
created entry.
|
||||
|
||||
## Interested?
|
||||
|
||||
If you're interested in Vieter, considering joining
|
||||
[#vieter:rustybever.be](https://matrix.to/#/#vieter:rustybever.be) on Matrix!
|
||||
The source code can be found on my personal
|
||||
[Gitea](https://git.rustybever.be/vieter/vieter).
|
||||
99
content/blog/vieter-0.5.0/index.md
Normal file
99
content/blog/vieter-0.5.0/index.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
title: "Announcing Vieter 0.5.0"
|
||||
date: 2022-12-29
|
||||
---
|
||||
|
||||
As 2022 comes to a close, and in the middle of exams, I'm ready to release
|
||||
another version of Vieter!
|
||||
|
||||
## What's Vieter?
|
||||
|
||||
As usual, a small refresher on what Vieter actually is for the new readers.
|
||||
Vieter provides two main services: a Pacman repository server and a build
|
||||
system for publishing Arch packages to said server. The goal is to fully
|
||||
replace any need for an AUR helper, with the AUR packages being built "in the
|
||||
cloud" instead. Of course, one can also publish their own packages to this
|
||||
server, allowing you to create your very own customized Arch repositories!
|
||||
|
||||
## What's changed?
|
||||
|
||||
### Server-agent architecture
|
||||
|
||||
The biggest change this version introduces is the migration to a polling-based
|
||||
server-agent architecture.
|
||||
|
||||
Previous versions relied on a "cron daemon". This daemon needed to be deployed
|
||||
on every architecture the user wanted to build packages for, with the daemon
|
||||
periodically polling the server for the list of targets to build. All
|
||||
scheduling was done on the node performing the builds.
|
||||
|
||||
While this system served me well for a while, it did limit possibilities for
|
||||
improvement. Building on multiple servers wasn't possible, as the cron daemons
|
||||
had no way of synchronizing with each other, meaning they'd all run all builds.
|
||||
There was also no way for the server (or the user for that matter) to control
|
||||
these daemons; they had a fixed build schedule that could only be changed by
|
||||
changing a target's configuration.
|
||||
|
||||
Due to these limitations, I've decided to revamp the build system & convert it
|
||||
to a server-agent architecture! With this new system, the main server handles
|
||||
all scheduling. On each server running builds, a "build agent" is deployed
|
||||
which periodically polls the main server for new jobs. This allows a Vieter
|
||||
instance to run builds on an arbitrary number of build nodes! Thanks to this,
|
||||
I'm able to run 137 builds in under 40 minutes, whereas before, I needed this
|
||||
time to process less than half of that :) As a bit of a stress test for my
|
||||
instance, I've started replicating the EndeavourOS repository for fun.
|
||||
|
||||
With the main server now being in control of scheduling, I've also been able to
|
||||
implement manual scheduling of builds on the server. If a package needs to be
|
||||
rebuilt, you can simply send an HTTP request (or use the accompanying CLI
|
||||
command) to schedule a build job.
|
||||
|
||||
### Quality-of-life improvements
|
||||
|
||||
This release was mostly the build system redesign, but I've also added some QoL
|
||||
improvements. Noteable additions are the option to periodically remove logs, as
|
||||
an active Vieter instance can collect thousands over time. The CLI tool should
|
||||
now also be a lot more stable, and will correctly display HTTP errors if
|
||||
needed. There's also the option to specify what subdirectory of a Git
|
||||
repository to use for a build. This is for example useful when building
|
||||
packages using a Git repository [containing multiple
|
||||
PKGBUILDs](https://github.com/endeavouros-team/PKGBUILDS).
|
||||
|
||||
## What's to come?
|
||||
|
||||
My brain never stops, so I still have a lot of cool ideas I wish to implement
|
||||
in the coming months.
|
||||
|
||||
For starters: better build awareness. The build system right now does not track
|
||||
the progress of jobs. Once a job is dispatched to an agent, the main server
|
||||
forgets about it and moves on. If a build fails due to unknown means causing
|
||||
the logs to never be uploaded, it'll be as if the build never happened. I'd
|
||||
like to change this. I want the main server to be aware of what jobs are
|
||||
running, have failed, or have perhaps timed out. This information could then be
|
||||
made available through the API, providing the user with valuable insight into
|
||||
the workings of their Vieter instance.
|
||||
|
||||
Building on this idea, I wish to know what specific command caused the build to
|
||||
fail. Was it makepkg, an HTTP error? And if it was makepkg, what error code?
|
||||
can the build system respond to it by itself? The main goal is to provide a
|
||||
deeper understanding into the workings of builds and the build system as a
|
||||
whole.
|
||||
|
||||
Another big one to tackle is API access to the repositories. These are
|
||||
currently only accessible through Pacman, but having this information available
|
||||
as a convenient REST API, useable from the CLI tool, sounds like a valuable
|
||||
asset. This would pave the way towards repository-level configuration.
|
||||
|
||||
Of course there's a lot more ideas, but the list would be too long to put here
|
||||
;p
|
||||
|
||||
## Conclusion
|
||||
|
||||
As you can see, I still have *a lot* of ideas for Vieter. As usual however, I
|
||||
can't predict when any of these features will get implemented. It all depends
|
||||
on whether the uni life leaves me some time :)
|
||||
|
||||
If you're interested in Vieter, considering joining
|
||||
[#vieter:rustybever.be](https://matrix.to/#/#vieter:rustybever.be) on Matrix!
|
||||
The source code can be found on my personal
|
||||
[Gitea](https://git.rustybever.be/vieter-v/vieter).
|
||||
62
content/blog/vieter-0.6.0/index.md
Normal file
62
content/blog/vieter-0.6.0/index.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
title: "Announcing Vieter 0.6.0"
|
||||
date: 2023-07-20
|
||||
---
|
||||
|
||||
It's been a while since I've released a new version of Vieter. A busy semester
|
||||
combined with a lack of interest in the project has definitely slowed down
|
||||
development. Nonetheless, I've got a new release ready for you!
|
||||
|
||||
## What's Vieter?
|
||||
|
||||
Vieter consists of two central components: an Arch Linux (well, Pacman
|
||||
actually) repository server that supports uploading package archives, combined
|
||||
with a build system to populate this server by periodically building select
|
||||
packages. The goal of this is to completely remove the need for an AUR helper,
|
||||
and moving all build times to the cloud, allowing for smooth updates across as
|
||||
many machines as required.
|
||||
|
||||
## What's changed?
|
||||
|
||||
This is a rather small update, and it mostly contains a few quality-of-life
|
||||
improvements.
|
||||
|
||||
For one, there's now a Prometheus metrics endpoint so you can integrate Vieter
|
||||
into your existing stack. Currently the metrics are limited to API request
|
||||
timings, but this could be expanded upon in the future.
|
||||
|
||||
The API can now filter the list of targets, allowing you to more easily search
|
||||
for specific targets. This functionality has also been added to the CLI.
|
||||
|
||||
Builds can now be configured with a timeout, with build containers being
|
||||
automatically killed if this timeout is reached.
|
||||
|
||||
Behind the scenes, the codebase has been updated to a compiler commit after the
|
||||
0.3.3 release, and the cron logic has been rewritten in C using the
|
||||
[libvieter](https://git.rustybever.be/vieter-v/libvieter) library. Agents now
|
||||
use worker threads, meaning they will not spawn a new thread anymore for each
|
||||
new build. Package uploads now properly fail if the TCP connection was closed
|
||||
before all bytes of a file were received. Lastly, the deprecated cron daemon
|
||||
has been removed.
|
||||
|
||||
### What's next?
|
||||
|
||||
Throughout the last couple of months, I've grown more and more tired of the V
|
||||
programming language, and the codebase in general. There's a lot of technical
|
||||
debt present, and due to the limitations of the language and existing
|
||||
frameworks, I've had to resort to questionable practices for a lot of the
|
||||
features (e.g. POST request data as query parameters). Due to this, I've
|
||||
decided to restart this project in Rust, under the name
|
||||
[rieter](https://git.rustybever.be/Chewing_Bever/rieter). With this, I hope to
|
||||
move away from this technical debt, and build a new solid foundation on which I
|
||||
can further expand this project. I'm not going to be making any promises on
|
||||
when this will be ready to replace Vieter, but I hope to get there soon.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Just picture a very creative ending of this post here ;)
|
||||
|
||||
If you're interested in Vieter, consider joining
|
||||
[#vieter:rustybever.be](https://matrix.to/#/#vieter:rustybever.be) on Matrix!
|
||||
The source code can be found on my personal
|
||||
[Gitea](https://git.rustybever.be/vieter-v/vieter).
|
||||
100
content/blog/vlang/index.md
Normal file
100
content/blog/vlang/index.md
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
---
|
||||
title: "My Experience With V"
|
||||
date: 2022-06-26
|
||||
draft: true
|
||||
---
|
||||
|
||||
For the last half a year or so, I've written code nearly exclusively in the V
|
||||
programming language (excluding college projects). In this time, I've learned a
|
||||
lot about the language, as well as being an active member of the community.
|
||||
|
||||
I don't recall exactly how I discovered V. being the kind of nerd that has a
|
||||
list of languages they wanna try, I probably saw it somewhere & added it.
|
||||
Luckily, V was the one I wanted to try out the most. After visiting
|
||||
[vlang.io](https://vlang.io/), I joined the Discord server & that's where the
|
||||
fun began!
|
||||
|
||||
Before I talk about the language itself, I would like to take a moment to
|
||||
appreciate the community. I felt welcome the moment I joined, and everyone
|
||||
(especially the V developers) was very helpful with any questions I had. If it
|
||||
wasn't for their help, [Vieter](https://git.rustybever.be/vieter-v/vieter)
|
||||
probably wouldn't be as far along as it is today!
|
||||
|
||||
## What's V?
|
||||
|
||||
While I'm not interested in giving a full description of the language, a short
|
||||
introduction is in order. V is a compiled programming language with a syntax
|
||||
very similar to Go. The main compiler backend transpiles V to C, providing
|
||||
interopt with C code without any effort. This also gives the compilation phase
|
||||
access to all optimisations that C compilers have to offer, resulting in very
|
||||
fast & optimized binaries. I'd list more things, but then it wouldn't be short
|
||||
anymore!
|
||||
|
||||
## Developing in V
|
||||
|
||||
Now for the relevant part of this post, the actual developing!
|
||||
|
||||
Developing locally in V is pretty straightforward. Write some code, run `v .`,
|
||||
blink, see if you made a mistake, repeat. For me, this is a very important
|
||||
feature of V. Not only does the compiler handle the "build system" for you;
|
||||
it's also incredibly fast. This is accomplished by using the tcc compiler, a
|
||||
small & extremely fast C compiler, for development builds. Thanks to this,
|
||||
compiling my code doesn't take me out of "the flow"; a problem that I've faced
|
||||
when working with Rust code, as I'm very sensitive to losing focus.
|
||||
|
||||
Building optimized binaries is equally simple; just run `v -prod .`. This will
|
||||
use either gcc or clang to compile your code using the max optimisation levels.
|
||||
|
||||
Due to the rapidly developing nature of V, it is possible that old code no
|
||||
longer compiles on a newer compiler. This won't happen once the language is
|
||||
stabilized, but as of today, changes can occur. I don't actually know how
|
||||
others handle this, but I personally maintain a mirror of the compiler that I
|
||||
update regularly. This way, I decide when code might break, meaning I can react
|
||||
quickly to make sure nothing stays broken for long. This brings me to my CI
|
||||
setup!
|
||||
|
||||
Because overengineering is fun, I have my own CI server that I use to test &
|
||||
deploy basically everything I create; V software is no exception! Using Docker
|
||||
buildx, I create multi-architecture Alpine-based images containing my compiler
|
||||
fork & any C library dependencies that I use. These images are then used in my
|
||||
CI to build statically compiled binaries that I can use to create the actual
|
||||
Docker images! Due to V compiling to C, compiling static binaries is quite
|
||||
simple; just build using a musl-based OS such as Alpine Linux.
|
||||
|
||||
Enough drooling over my CI, back to V! Yes, when I was writing code in V, I
|
||||
encountered some bugs in the compiler. While a bit inconvenient at times, they
|
||||
definitely weren't a showstopper for me. V is still a developing language; I'm
|
||||
not gonna try to advertise that it isn't. The thing is though, I was able to
|
||||
report these compiler bugs to the community immediately, many of which being
|
||||
fixed within 24 hours by one of the V developers! V might still be in
|
||||
development, but it's definitely already ready for developing projects. My
|
||||
[vieter](https://git.rustybever.be/vieter-v/vieter) project has nearly 4k SLoC
|
||||
and still compiles just as quickly as when I started it. The resulting binaries
|
||||
are rock-solid; my personal Vieter instance has been running for months without
|
||||
issues.
|
||||
|
||||
## Conclusion?
|
||||
|
||||
It's clear from this post that I've taken a liking to V. The amount of
|
||||
evolution I've seen in the months that I've been using it is impressive, and
|
||||
I'm certain that V will reach its goal of being a stable language. I'm fine
|
||||
tagging along until that day comes :)
|
||||
|
||||
In the context of developing Vieter, I've written a multitude of software
|
||||
pieces, ranging from a cron daemon to a rewrite of Arch Linux's `repo-add`
|
||||
command. This variety gives me confidence that V can already be used to develop
|
||||
varied & complex software.
|
||||
|
||||
Besides developing Vieter, I'd like to enrich the ecosystem with packages that
|
||||
I think will be useful for everyone. To this end, I've started splitting off
|
||||
modules of the Vieter codebase & developing them independently. My first goal
|
||||
will be writing a Docker client
|
||||
[library](https://git.rustybever.be/vieter-v/docker), as I find this to be very
|
||||
useful for any language to have (and also I need it myself of course).
|
||||
|
||||
Now, I know using these new and/or developing languages is not for everyone.
|
||||
Some just prefer sticking to the proven titans of the industry, and that's
|
||||
fine. However, for those like me that love using these new langs, I really do
|
||||
recommend checking out V. It's fast, it's of course free and open-source, and
|
||||
using a language is one of the best ways of helping it move forward. Perhaps
|
||||
when you join, you'll see a Chewing Bever babbling on ;)
|
||||
17
content/blog/welcome.md
Normal file
17
content/blog/welcome.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: "Welcome!"
|
||||
date: 2022-03-31
|
||||
---
|
||||
|
||||
After months of delaying, I've finally set up my own little site! Initially I
|
||||
had this grand idea in mind with lots of overengineering, but eventually I was
|
||||
able to overcome my stubbornness and just use [Hugo](https://gohugo.io/).
|
||||
|
||||
I hope to post something semi-regularly here (I might even try the [100 Days To
|
||||
Offload](https://100daystooffload.com/) challenge if I feel like it). I haven't
|
||||
really decided on what type of content I wish to publish, but chances are I'll
|
||||
just be writing about whatever I feel like ;p
|
||||
|
||||
If you're interested, you can follow my [RSS feed](/index.xml)!
|
||||
|
||||
Have a nice day :)
|
||||
37
content/blog/workflow/index.md
Normal file
37
content/blog/workflow/index.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
title: "My Workflow For This Site"
|
||||
date: 2022-04-05
|
||||
---
|
||||
|
||||
This blog is about a week old now. I'm still figuring out what kind of content
|
||||
I'd like to post, or what kind of writing style I have. What I have figured out
|
||||
however, is my workflow.
|
||||
|
||||
Thanks to my backend [powered by Axum](/switch-to-axum) I have pretty much full
|
||||
creative control over the internal workings of my site. This gave me the
|
||||
freedom to implement a system that I think works very well. Let's elaborate a
|
||||
bit.
|
||||
|
||||
Both the blog & the documentation part of my website are currently being
|
||||
generated using Hugo, a static site generator. The lack of JavaScript makes the
|
||||
site very fast, which is always a big plus in my opinion. Thanks to my
|
||||
[self-hosted CI](https://woodpecker-ci.org/), I can automatically build &
|
||||
deploy the static files every time I update anything. My CI builds the static
|
||||
website, compresses it into a tarball, & uploads this to my backend. This
|
||||
process takes less than 10 seconds on a warm CI runner & it allows me to very
|
||||
quickly update my site, correct errors, or just upload a post like this one!
|
||||
|
||||
My backend supports a simple system of serving multiple sites. In practice this
|
||||
means that I can specify which site I'm uploading using a query parameter in
|
||||
the POST request. This is how I'm able to serve my documentation on
|
||||
[/docs](/docs) while still having my blog available as the "default" site.
|
||||
|
||||
The "source code" for my site(s) is stored in Git repositories using Markdown.
|
||||
Considering I use Git on a daily basis, this is perfect for me & I don't see it
|
||||
as an "extra step" anymore. For college I use Git as well, so using it in
|
||||
personal projects is a no-brainer.
|
||||
|
||||
I have no idea how common this setup is, or if it'll work as well down the
|
||||
road, but for now, I find it works perfectly.
|
||||
|
||||
Thanks for reading!
|
||||
Loading…
Add table
Add a link
Reference in a new issue