Monthly update, November 2023
Projects
I've slowed down a little in November to do some repairs on my house. I think it's healthy to spend time on practical work, not just typing ahead on the keyboard!
nsblast
I spent most of the time implementing the web UI using React, and implementing API features I required along the way. It's interesting how different an API look when you consume it, than it did when you designed it ;)
The UI work moved slowly, as it's the first time I make a front end using "modern tools". React is relatively easy to grasp, but I'm not implementing a landing page for some brand. For example, the dialog I use to edit Name Server Resource Records have different properties depending on the type of the resource record. For example, a CNAME has only a string, while a SOA record has a handful of strings and numbers. The "Add Resource Record" dialog need to adapt seamlessly to the correct input types, based on the selection of a drop-down list. Easy to do with QT/QML. A little more tricky with React (at least at my level).
There are probably still a few weeks to go before I'm satisfied with the UI.
mkres
I re-wrote mkres from scratch in C++20, added some much needed features like directory scanning, filtering and compression. I also changed the storage type to make it more compact.
Mkres is a utility I use to embed files as code in C++ projects. Nsblast's embedded HTTP server can serve both swagger and the React based UI directly from memory. This makes the executable file larger, but it simplifies deployment. All that is required is the 'nsblast` binary file and a few system libraries (and the avalanche of Google shared libraries required by grpc).
I have not spent much time with C++20 ranges in the past, so I spent a few days extra with mkres to play with this feature, and implement the gzip compression as a std::range transformer. The code that compress (or don't) look like this:
1
2 auto formatter = [&config](ostream& out, const path_t& path) {
3
4 ifstream data_stream(path, ios_base::in | ios_base::binary);
5 data_stream.unsetf(ios_base::skipws);
6
7 auto input_range = ranges::istream_view<char>{data_stream}
8 | ranges::views::transform([](const auto ch) {
9 return byte{static_cast<uint8_t>(ch)};
10 });
11
12 out << " // " << path << endl;
13
14 if (config.compression == "gzip") {
15 auto compressor = jgaa::ranges::zlib::gz_compressor<decltype(input_range)>(input_range);
16 format_data(out, compressor);
17 } else {
18 format_data(out, input_range);
19 }
20 };
21
The whole pipeline from disk file to generated C++ code in another disk file is lazy, meaning that memory consumption during generation is relatively low.
Next-app
I'm also spending brain juice on Next-app, my upcoming Getting Things Done application. I have lots of exiting ideas. I hope to start coding soon!
I was thinking about writing the back-end in Rust. But I'll probably use C++ in stead for now.
At this point, the plan is to:
- Write a back-end in C++20 using Postgres or MariaDB for storage. Originally I planned to use ArangoDB for storage, as it has some really nice features for this kind of app. But they changed their licence away from Open Source some months ago, so I'll go with a safer storage solution.
- Use grpc for communication between the app and the backend. It's faster and simpler to use than a REST API, especially after the research into GRPC I did earlier this year.
- Use C++20 and QT 6/ QML for the desktop and mobile applications.