[{"content":"Description The microkernel architecture pattern is a way to structure an application as a set of loosely coupled, collaborating components. Each component has a specific responsibility or function, and each communicates with other components through well-defined interfaces. This pattern is used to build systems that can be easily extended, modified, and tested.\nIt is commonly used in systems that need to support a wide range of features or configurations. Some examples include:\nOperating Systems Web Servers Your favorite IDE Ruby Web Browsers Office Suites Terminal Emulators How it works The microkernel pattern is based on the idea of separating core functionality from additional features. The core functionality is implemented in a small, lightweight kernel, while additional features are implemented as plugins or modules that can be added or removed as needed.\nHere\u0026rsquo;s a simple example of how this might work in a Go application:\nLet\u0026rsquo;s define a simple plugin interface: type Plugin interface { Start() Stop() } We can then define a kernel struct that will manage the plugins: type Kernel struct { plugins []Plugin } We can then add methods to the kernel to add and remove plugins: func (k *Kernel) AddPlugin(p Plugin) { k.plugins = append(k.plugins, p) } func (k *Kernel) Start() { for _, p := range k.plugins { p.Start() } } func (k *Kernel) Stop() { for _, p := range k.plugins { p.Stop() } } Finally, we can define a simple plugin that logs to a file: type Logger struct { logFile *os.File } func (l *Logger) Start() { var err error l.logFile, err = os.Create(\u0026#34;log.txt\u0026#34;) if err != nil { log.Fatal(err) } } func (l *Logger) Stop() { l.logFile.Close() } We can then create a kernel, add the logger plugin, and start the kernel: func main() { k := \u0026amp;Kernel{} logger := \u0026amp;Logger{} k.AddPlugin(logger) k.Start() // Do some work k.Stop() } Diagram Pros Focus on core functionality and delegate other tasks to plugins Plugins can be developed, tested, and released in isolation Creates a modular and flexible architecture Loosely coupled components Can create entire ecosystems around the core functionality Clearly defined interfaces between components Cons Backward compatibility can be challenging if there\u0026rsquo;s a desire to change the core functionality Can be difficult to manage dependencies between components If security is a concern plugins can introduce vulnerabilities if untethered If not managed properly, the core can become bloated with features When to Use I\u0026rsquo;d recommend using the microkernel architecture in some of the following scenarios:\nYou need to support a wide range of features or configurations You want to create a modular and flexible architecture You want to create an ecosystem around the core functionality You want to delegate non-core functionality to plugins ","permalink":"/posts/microkernel-software-architecture/","summary":"Description The microkernel architecture pattern is a way to structure an application as a set of loosely coupled, collaborating components. Each component has a specific responsibility or function, and each communicates with other components through well-defined interfaces. This pattern is used to build systems that can be easily extended, modified, and tested.\nIt is commonly used in systems that need to support a wide range of features or configurations. Some examples include:","title":"Microkernel Software Architecture"},{"content":" \u0026ldquo;a hybrid of microservices architecture style and is considered one of the most pragmatic architecture styles, mostly due to its architectural flexibility.\u0026rdquo; \u0026ndash; \u0026ldquo;Fundamentals of Software Architecture\u0026rdquo; by Mark Richards \u0026amp; Neal Ford\nDescription If done correctly, Service Based Architecture (SBA) can be incredibly flexible, yet simple to build and maintain.\nI think of SBA\u0026rsquo;s as I would a three-layer CRUD app: there\u0026rsquo;s a frontend, a backend, and a persistence layer. Now instead of backend we should think service.\nWhat\u0026rsquo;s a service? In this context a service is typically a REST API server that performs business logic in its specific domain.\nA service in this stack could also be something like a queue worker which wouldn\u0026rsquo;t require a REST API.\nIn practice, the service is whatever you decide you need.\nVariants SBA\u0026rsquo;s flexibility allows for variations from it\u0026rsquo;s traditional definition and can adapt to your applications needs.\nFind that sharing the same database across all services creates too much coupling? Create a database for each service.\nFind that you\u0026rsquo;d really prefer to use a messaging service and an event log? Go ahead!\nBut with this flexibility comes common pitfalls. Data can sometimes get stored too far from where it\u0026rsquo;s needed for processing. Services can become tightly coupled, creating an environment where the same work is spread across multiple services.\nDiagram Shared Database Isolated Database Pros Domain-partitioned architecture can have an overall positive effect on project Incredibly flexible and resilient Can change with business requirements As a distributed system it can scale services independently Stepping stone to microservices Cons Flexibility allows for lots of chance to cut corners While this can resemble microservices, it does not come with the methodologies and opinionated design restrictions, leading to a false sense of scalability in distributed system If untethered or unwatched, complexity and coupling between services can run rampant When to Use I\u0026rsquo;d recommend using SBA in some of the following scenarios:\nSmall team, budget, or timeline Knowing very little of your final business requirements Or you anticipate they may change rapidly Small teams that need some flexibility when designing, building, and shipping features Having a desire to separate technology by domain into reusable components ","permalink":"/posts/service-based-architecture/","summary":"\u0026ldquo;a hybrid of microservices architecture style and is considered one of the most pragmatic architecture styles, mostly due to its architectural flexibility.\u0026rdquo; \u0026ndash; \u0026ldquo;Fundamentals of Software Architecture\u0026rdquo; by Mark Richards \u0026amp; Neal Ford\nDescription If done correctly, Service Based Architecture (SBA) can be incredibly flexible, yet simple to build and maintain.\nI think of SBA\u0026rsquo;s as I would a three-layer CRUD app: there\u0026rsquo;s a frontend, a backend, and a persistence layer.","title":"Service Based Architecture"},{"content":"Background With AI and ML in the limelight and hardware refreshes taking place, now seemed like a good time to try out utilizing some spare Nvidia 3070 TI cards and picking up some dirt cheap Tesla M40 24GB cards.\nAfter a little research I settled on using Ubuntu 22.04.4 LTS as my server operating system.\nIt\u0026rsquo;s no mystery that having a lot of Ubuntu users creating and updating documentation along with answering posts creates draw for more Ubuntu users. So yes, this decision was driven by market saturation, updated documentation, and prolific amounts of stackoverflow posts.\nWarnings \u0026amp; Gotchas Hardware I\u0026rsquo;ve used these steps successfully with the following Nvidia cards:\nTesla M40 24GB These cards make up the bulk of my homelab CUDA count RTX 3070 Ti 8GB Ventus 3X Series RTX 3070 LHR 8 GB Zotac GAMING Twin Edge OC Secure Boot If Secure Boot is enabled, be prepared to handle creating a new secure key and manually entering the new key before the system can reboot.\nHow to Reset / Wipe Clean If something goes wrong and you need to reset:\nsudo apt-get remove --purge \u0026#39;^nvidia-.*\u0026#39; sudo apt-get remove --purge \u0026#39;^libnvidia-.*\u0026#39; sudo apt-get remove --purge \u0026#39;^cuda-.*\u0026#39; sudo apt autoremove -y sudo reboot now sudo apt-get install linux-headers-$(uname -r) Prerequisites Blacklist Nouveau Create the file /etc/modprobe.d/blacklist-nouveau.conf and prevent nouveau from loading.\nOpen the file for editing:\nsudo vim /etc/modprobe.d/blacklist-nouveau.conf Add the following lines:\nblacklist nouveau options nouveau modeset=0 Regenerate the kernel initramfs:\nsudo update-initramfs -u Choose your installation method (Preferred) Package Manager Install I\u0026rsquo;ve ended up preferring this installation method as it\u0026rsquo;s easier to manage. I did explore the local installer without much success, and I don\u0026rsquo;t believe I\u0026rsquo;d recommend it if you\u0026rsquo;re a casual homelabber like myself.\nOfficial Documentation CUDA The top level official documentation docs/common-installation-instructions-for-ubuntu Direct link to the common installation instructions for Ubuntu /cuda-downloads for ubuntu 22 Download page that will provide you with the correct and updated URLs for your rig Keyring and Toolkit We need the toolkit before the drivers.\n# Get the latest URL from download page ^^ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt-get update sudo apt-get -y install cuda-toolkit Now Choose Your Driver Adventure Note: If secure boot is enabled, you will need to create a new secure key and type that in prior to the system booting. (This means you may have to do like I did, and grab a spare monitor and keyboard for this.)\nThe documentation provides two options for drivers, which they describe as \u0026ldquo;Legacy\u0026rdquo; and \u0026ldquo;Open Source\u0026rdquo;.\nIn my case, and I\u0026rsquo;m guessing because I\u0026rsquo;m using last gen cards, only the \u0026ldquo;Legacy\u0026rdquo; drivers worked for me.\nLegacy Drivers (worked on 3070\u0026rsquo;s and M40\u0026rsquo;s)\nsudo apt-get install -y cuda-drivers # I\u0026#39;ve found that this is not necessary, but some people seem to recommend it at this point # sudo reboot now Did not work for me, but here are the commands for Open Source drivers:\nsudo apt-get install -y nvidia-kernel-open-545 sudo reboot now sudo apt-get install -y cuda-drivers-545 GDS sudo apt-get install nvidia-gds Output: Backing up initrd.img-5.15.0-89-generic to /boot/initrd.img-5.15.0-89-generic.old-dkms Making new initrd.img-5.15.0-89-generic (If next boot fails, revert to initrd.img-5.15.0-89-generic.old-dkms image) update-initramfs....... Note: I\u0026rsquo;ve seen: \u0026ldquo;modprobe: ERROR: could not insert \u0026rsquo;nvidia_fs\u0026rsquo;: No such device\u0026rdquo; appear here at the end, but upon reboot GDS was working.\nUpdate your shell Either update your PATH and LD_LIBRARY_PATH exports or enter them:\nOpen up your profile\nvim ~/.zshrc # or ~/.bashrc Add the following lines:\nexport PATH=$PATH:/usr/local/cuda-12/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-12/lib Reboot We do need to reboot here. If you have Secure Boot, now is the time when you\u0026rsquo;ll need to enter the new key password.\nsudo reboot now Verify Once you\u0026rsquo;re back up you can verify your installation and that your paths are set by entering:\nnvidia-smi You should see something like: Docker Setup Documentation https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html Install from Package Manager sudo apt-get install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker sudo nvidia-ctk runtime configure --runtime=containerd sudo systemctl restart containerd Verify sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi Output Samples You can run some samples from the Nvidia repo \u0026ndash; here\u0026rsquo;s a quick example:\ngit clone https://github.com/nvidia/cuda-samples cd cuda-samples make These can take a while to build, but I\u0026rsquo;ve found a few of theme useful when verifying my setup.\nCommands like:\n./bin/x86_64/linux/release/deviceQuery ./bin/x86_64/linux/release/bandwidthTest You can try to run these wih --help to see what they do and what options you can pass them.\nExample:\n","permalink":"/posts/homelab-cuda-ubuntu-server/","summary":"How to set up CUDA on Ubuntu 22 Server with Docker Support.","title":"Homelab: CUDA on Ubuntu 22 Server with Docker Support"},{"content":"Background I’ve been pretty excited to pick up nodejs for awhile now and I sat down today to get the ball rolling. I’ve installed node before and ran the basic ‘hello world’ example at work so I wanted to get right into it. Since I was anxious to at least get something out there on hour zero so I jumped straight into Heroku and created an app. While the process worked great and I got something up I was so excited about node that I committed to picking it up and putting own server.\nAnd that’s the first blocker. Sure - I want to put it on own server\u0026hellip; but I run a lot of other things on my boxes. One of those things is a preexisting LAMP stack that hosts some tools that it would be tough to replace or go without. So that’s when my googling started.\nI knew going into this that I was going to need to either need a second IP address or use a proxy. I opted for the path of least resistance and most practical: Proxy.\nNot surprisingly there are a lot of brain dumps out there on this very subject, but I found them fairly tough to follow. Everyone has a stackoverflow question or forum post on how to tackle this problem and even a few “is this even ok?” questions.\nInstall Node and npm This one is pretty straight forward.\nFollow these steps and you’ll be set. https://gist.github.com/isaacs/579814#file-node-and-npm-in-30-seconds-sh\nMy only one add here is that I actually needed to add the local bin folder ~/local/bin to my ~/.bash_profile on MacOSX. I did not have this problem when installing on my Ubuntu box though.\nEdit Local Server, /etc/hosts and Open Port I knew I was about to start redirecting from localhost to localhost, so I wanted to ensure that my Ubuntu server knew that my domain.com was the same as 127.0.0.1 to prevent any type of 503’s. Along this line I also went ahead and opened the 5000 port on my network. You can choose any port of your own, anything in that range should work.\nEdit Apache And now for the important stuff\u0026hellip; the proxy.\nThis will install the Apache2 mod_proxy to /etc/apache2/mods-available/ and /etc/apache2/mods-enabled/\nsudo a2enmod proxy sudo a2enmod proxy_http Then, I needed to edit my default conf:\nProxyRequests Off \u0026lt;Proxy *\u0026gt; Order deny,allow Allow from all \u0026lt;/Proxy\u0026gt; \u0026lt;Location /node\u0026gt; ProxyPass http://myawesomedomain.com:5000 ProxyPassReverse http://myawesomedomain.com:5000 \u0026lt;/Location\u0026gt; Then restart apache:\nsudo service apache2 restart\nSpawn A Node Instance \u0026amp; Hello World! web.js var express = require(\u0026#34;express\u0026#34;); var app = express(); app.use(express.logger()); app.get(\u0026#39;/\u0026#39;, function(request, response) { response.send(\u0026#39;Hello World!\u0026#39;); }); app.get(\u0026#39;/test\u0026#39;, function(request, response) { response.send(\u0026#39;This was only a test\u0026#39;); }); app.use(function(err, req, res, next){ console.error(err.stack); res.send(500, \u0026#39;Something broke!\u0026#39;); }); var port = process.env.PORT || 8080; app.listen(port, function() { console.log(\u0026#34;Listening on \u0026#34; + port); }); package.json { \u0026#34;name\u0026#34;: \u0026#34;node-example\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;0.0.1\u0026#34;, \u0026#34;dependencies\u0026#34;: { \u0026#34;express\u0026#34;: \u0026#34;3.1.x\u0026#34; }, \u0026#34;engines\u0026#34;: { \u0026#34;node\u0026#34;: \u0026#34;0.10.x\u0026#34;, \u0026#34;npm\u0026#34;: \u0026#34;1.2.x\u0026#34; } } After this we can then run npm install from our node app directory, then:\nsudo node web.js\nPoint our browsers to myawesomedomain.com/node and… success. :)\n","permalink":"/posts/nodejs-apache-same-ubuntu-server/","summary":"Background I’ve been pretty excited to pick up nodejs for awhile now and I sat down today to get the ball rolling. I’ve installed node before and ran the basic ‘hello world’ example at work so I wanted to get right into it. Since I was anxious to at least get something out there on hour zero so I jumped straight into Heroku and created an app. While the process worked great and I got something up I was so excited about node that I committed to picking it up and putting own server.","title":"Apache and Node.js on the same Ubuntu Server"},{"content":"I recently opened up an old .htaccess and I was struck with the memory of how much it sucked trying to Google search for some real, working, answers on making short urls.\nSo here you go, my quick tip on what you really want to know about mod_rewrite.\nIf you want an actual explanation of what is going on here it’s at the bottom.\nRewrite Conditions # File: .htaccess # File Location: / RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+) /index.php [L] // File: index.php // File Location: / $urlArray = $_SERVER[\u0026#39;REQUEST_URI\u0026#39;]); array_shift($urlArray); // Gets rid of the blank first param. Now you have an array with all of your parts, and you can map them accordingly.\nQuick Hack If you have just a couple of pages that you want to look prettier:\n# File: .htaccess # File location: / RewriteEngine on # Start rewriting your urls RewriteRule ^home$ index.php RewriteRule ^about$ about.php And you just keep adding RewriteRule’s for each page. This is really only helpful when you just have a set of static looking pages for a site.\nExplanation RewriteEngine on Tells Apache to turn on the RewriteEngine for this folder RewriteCond %{REQUEST_FILENAME} !-f Read this as: We\u0026rsquo;ll rewrite the URL if the requested file can\u0026rsquo;t be found RewriteCond %{REQUEST_FILENAME} !-d Read this as: We\u0026rsquo;ll rewrite the URL if the directory can\u0026rsquo;t be found RewriteRule . /index.php [L] Then Rewrite this url to index.php, and make it the last redirect ","permalink":"/posts/apache-mod-rewrite-short-urls/","summary":"I recently opened up an old .htaccess and I was struck with the memory of how much it sucked trying to Google search for some real, working, answers on making short urls.\nSo here you go, my quick tip on what you really want to know about mod_rewrite.\nIf you want an actual explanation of what is going on here it’s at the bottom.\nRewrite Conditions # File: .htaccess # File Location: / RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME} !","title":"Apache mod_rewrite and Short Urls - What you really want to know."},{"content":" Nov 11, 2013 I’ve updated the code examples and provided them on github at: https://github.com/dschreck/php-eav-example\nI want to share with some of you an easy way to set up your database design in a very flexible and reliable EAV like model.\nEAV stands for Entity Attribute Value, which is a common design for complex database structures that require many different Entities using many different attributes with, again, many different values. It’s very common to find this set up in medical offices or records.\nLet’s go ahead and assume a situation, and we’ll work through it.\nLet’s say you’re accepting a feed of some sort, and you need to save the items being fed to you into a database. The problem here, is that the content length of these items, attributes, and values varies.\nSo let’s consider the following:\nItem \u0026#39;Node1\u0026#39; -\u0026gt; Attribute \u0026#39;Main\u0026#39; -\u0026gt; Value 1 Value 2 Value 3 Value 4 Item \u0026#39;Node2\u0026#39; -\u0026gt; Attribute \u0026#39;Main\u0026#39; -\u0026gt; Value 1 Value 2 Value 3 Value 4 Attribute \u0026#39;Other\u0026#39; -\u0026gt; Value 1 Value 2 Item \u0026#39;Node3\u0026#39; -\u0026gt; Attribute \u0026#39;Main\u0026#39; -\u0026gt; Value 1 Value 2 Value 3 Value 4 Value 5 Value 6 Value 7 Value 8 Now this is a very cheap and generic example of a data structure. But we’ll work with it for now.\nSo let’s go ahead and draw some conclusions.\nThe Item list will come in with a name, and have Attributes. These attributes will have values. But the number of attributes and the number of values varies.\nSo with that in mind, we shall come up with some SQL to create some times. For this example we’re going to need three tables: items, item_attributes, and attribute_values.\nSo here we go:\n-- MySQL Example -- first our items table: CREATE TABLE `items` ( `id` int(11) NOT NULL auto_increment, `item_name` varchar(50) default NULL, PRIMARY KEY (`id`) ); -- now our item attributes CREATE TABLE `item_attributes` ( `id` int(11) NOT NULL auto_increment, `item_id` int(11) NOT NULL default \u0026#39;0\u0026#39;, `attribute_name` varchar(50) default NULL, PRIMARY KEY (`id`), KEY `item_id_attribute_name` (`item_id`,`attribute_name`) ); -- now finally our attribute values CREATE TABLE `attribute_values` ( `attribute_id` int(11) NOT NULL default \u0026#39;0\u0026#39;, `attribute_value` varchar(100) default NULL, UNIQUE KEY `attribute_id` (`attribute_id`,`attribute_value`) ); Now that we have our layout, let’s take a look at how this is going to work:\nLet’s assume the following PHP array is a representation of our data…\n\u0026lt;?php // start up our array $data = array(); // // Now, let\u0026#39;s just load it with some test data $data[\u0026#39;item_1\u0026#39;] = array(); $data[\u0026#39;item_1\u0026#39;][\u0026#39;attribute_1\u0026#39;] = array(); $data[\u0026#39;item_1\u0026#39;][\u0026#39;attribute_1\u0026#39;][] = \u0026#39;value1\u0026#39;; $data[\u0026#39;item_1\u0026#39;][\u0026#39;attribute_1\u0026#39;][] = \u0026#39;value2\u0026#39;; $data[\u0026#39;item_1\u0026#39;][\u0026#39;attribute_1\u0026#39;][] = \u0026#39;value3\u0026#39;; $data[\u0026#39;item_1\u0026#39;][\u0026#39;attribute_1\u0026#39;][] = \u0026#39;value4\u0026#39;; // that\u0026#39;s good for now. /** * Now let\u0026#39;s insert this int our new schema * * Please note, for example sake, I will not be double checking queries * but you SHOULD check each query for an error. **/ foreach($data as $item_name =\u0026gt; $attributes) { $sql = \u0026#34;INSERT INTO items (id, item_name) VALUES (NULL, \u0026#39;{$item_name}\u0026#39;);\u0026#34;; mysql_query($sql); $item_id = mysql_insert_id(); // now let\u0026#39;s loop through our attributes foreach($attributes as $attribute =\u0026gt; $values) { // this is now our insert into the attributes... $sql = \u0026#34;INSERT INTO item_attributes (id, item_id, attribute_name) VALUES (NULL, {$item_id}, \u0026#39;{$attribute}\u0026#39;);\u0026#34;; mysql_query($sql); $attribute_id = mysql_insert_id(); // now let\u0026#39;s loop through the attribute values foreach($values as $value) { $sql = \u0026#34;INSERT INTO attribute_values (attribute_id, attribute_value) VALUES ({$attribute_id}, \u0026#39;{$value}\u0026#39;);\u0026#34;; mysql_query($sql); } } } And there you have it - that’s now how we can get our data into our database in a flexible manner, without having to rely on an ‘excel’ like database.\nTo get it out, we’ll simply use some joins…\n$sql = \u0026#34;SELECT items.item_name, ia.attribute_name, av.attribute_value FROM attribute_values AS av JOIN item_attributes AS ia ON (ia.id = av.attribute_id) JOIN items AS items ON (items.id = ia.item_id); \u0026#34;; You could also use a concat_ws to make a comma separated list, but now that you have it in your database, you can do anything you want with it!\n","permalink":"/posts/eav-modeling-with-php-mysql/","summary":"Entity-Attribute-Value (EAV) modeling is a way to store data in a flexible way. This article describes how to implement EAV in PHP and MySQL.","title":"EAV Modeling with PHP \u0026 MySQL"}]