💾 Archived View for lunacb.house › blog › 2022-10-23.gmi captured on 2024-02-05 at 09:36:35. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
created: 2022-10-23 01:20:18 UTC
modified: 2022-10-23 17:17:00 UTC
Wow, it's been a hot minute since I touched the blog. I do enjoy writing though, when I have the motivation and the inspiration, so I might try to do more often. Since I've been gone, I've been writing some small servers. One's completed so far, and another's going to enter into final stages of development not too far in the future. All of this is helping me to learn how servers work by writing them, as well as how to use the administration tools needed to run them, which makes for an adventurous time. I'm also in the beginning stages of educating myself about the Cloud specifically, mostly because it makes me more hireable at $BIG_COMPANY. not that I like $BIG_COMPANY though, he's kinda smelly and gross. I'd much prefer to work somewhere less evil, but this is work I can do that I won't actually hate, I guess. I have begun to enjoy working with Cloud software though, despite the massive amount of complexity introduced by the architectural pattern. A boring, normal server is what I started with though, which was nice and cozy to develop.
I started off with a server to play Chess on, which seemed simple enough for a first project. It took a month to complete, which is a bit longer than I expected, but I think it's a fairly decent piece of software, although lacking in polish. So, now you can play SSHCHESS, either here on this server or over on tilde.town with `town chess` if you have an account there (a) (b). I offloaded the actual network interconnectivity problem to ssh or your favorite remote shell program, so all I had to deal with was a Unix domain socket, which is a lot more reliable and easy to handle.
I wrote the software in Go, which means I first had to learn Go. Some the language is decent, but it has some annoying parts too. The syntax, specifically, was something the Go devs don't seem to be good at, in my experience. One instance of this odd behavior that I feel like ranting about is semicolons. Go automatically inserts them into your code JavaScript-style, as a sort of preprocessor step. This is already the worst way to deal with your hatred of semicolons (a fair thing to dislike, though), and it's worse because Go's rules for deciding where they should be inserted are horribly dumb (c). If you want to spread something like an if statement out over multiple lines, you may or may not see a cryptic error spit out by your compiler about unexpected semicolons somewhere in your code that doesn't actually exist in the file. maybe the Go devs all have editor displays with 300-character widths, and the problem never crossed their minds. There's plenty of other awkward things I don't like as well, like the ways in which Go enforces naming and code organization.
This isn't me saying that go is an Evil language, though. Most of it isn't that bad. Concurrency is pretty good. I'd never really worked with threads before, so my opinion doesn't count for too much, but they were surprisingly friendly to start out with in Go. Most of my programming life I'd been scared of threads, which seemed buggy and rude and didn't do too much you couldn't have already done without them. Having threads be isolated from eachother and share information primarily by passing messages makes them really easy to work with. They also help with a lot of Unix problems like waiting for events from multiple sources.
I also learned some SQL. For this project I used SQLlite, which made things nice and easy since it doesn't have a server. I got to read their documentation, which they decided to use flowcharts to describe syntax with for some reason. I think SQL queries are a pleasant thing to write, though. Maybe my opinion will change If I ever have to write some more complex queries. It felt a bit awkward to deal with weirdly-formatted or (more likely) out-of date tables in the SQL database. Your SQL queries seem to assume that you know for sure what SQL table you have and how they're organized, and doesn't give many introspective tools to verify that meta-information. Storing a version number in the table and panicking if it's wrong seems to be a perfectly workable solution, though. I also had to store some passwords in the database. I expected this to be hard, but after a bit of research it didn't end up being very bad. I just needed to use a function to hash the password when it goes in and unhash it when it goes out.
I also made a text protocol for the chess server. I think it overall went fairly well, although I had some trouble with race conditions. Specifically, what happens if a client sends a command relating to an object which has ceased to exist. I ended up having the client send an ID number with each message and having the server send back a confirmation message with that ID that indicates any errors. It seems to work, although I haven't specifically tested many of those race conditions, so it may break in some cases.
I did some research about the Cloud and how it separates everything into cute little Containers. They all get to do their own thing without caring about what the computer they're running on thinks. I actually expected software running on the cloud to require design using some special capacities to interface with the Super Cloud Overlords with cool API's, but it turns out they don't. For the most part, it's just the infrastructure they're running on that's different, and they can usually just be run directly on your computer if you try hard enough, which makes local testing easy.
I started by researching Kubernetes, and I learned plenty about the broad design of cloud infrastructure that way, but it was a bit too complex for me starting out, so I decided to research Docker to begin with instead. Docker is surprisingly easy to use, both to run images and to create new ones. I found it a bit inefficient at times, though, although Docker tries it's best to cache things. I didn't like how much work was given to a daemon with root privileges to do. Also, the speed at which my root partition filled up was impressive. I ended up symlinking docker's storage dirs to my home partition so I would't run out of space.
I also learned how much I hate capitalists. Stop talking about your weird "solutions" and "business logic" and "data lakes" and whatever else.
This is what I'm working on right now. A "cloud-native" service that very simply gives you a chatbox you can talk in. When you have multiple little micro-services all talking to each other, things start to get very complex very quickly. One problem I ran into is propagating messages to different instances of these microservices (in my case literal "messages" from the user). After thinking about the problem for a few moments I realized that it's not a trivial one to solve, and I started looking for other people's solutions to the problem. There are plenty of them, as expected, and they all have massive codebases. I don't know what these services manage to do to make the task of passing around messages as complex as they do, but that's an investigative adventure for another day.
I'm trying to make this thing as reliable as I possible can. No missed messages in the client or anywhere in the servers. I haven't gotten to the part where that really matters yet, so we'll see how that goes.
I want to learn to use more tools, is really the biggest thing. There's lots of them out there and I'm still a baby sysadmin. I also want to learn more about what my Programmer ancestors have been doing and read the source code of plenty of servers to absorb Good Ideas.
In the distant future, I'll be a Hot, Popular, Cute Sysadmin Witch with Four Girlfriends. I think all of the work here only helps with the Sysadmin part, but this is a very real future that will definitely happen.