Refactor into managed resources #14
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "resource-refactor"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
We want to address the learnings from PR #12 — move away from the clumsy imperative implementation for installing applications and managing server state, and instead towards a managed resource model.
However, many insights occurred in the process of completing this refactor.
Solution
It turns out that a tree was not the correct data structure to model resources and their dependencies. Unfortunately, nodes can have more than one parent.
The extra flexibility that a tree structure would have provided turned out to be unnecessary. Currently, it seems incredibly likely that the direction of dependency will never differ from application to application. For example, a service will always depend upon the files, a caddy rule will always depend upon firewall rules, etc. There's no reason to expect a file will ever depend on a service being enabled first, or a firewall rule that depends upon a caddy rule.
Crucially, this allows us to keep the application manifest schema quite simple. If the tree data structure had been necessary, the application manifest schema would have had to represent the precise location of each and every resource in the dependency tree. We want to keep the application manifest scheme as simple as possible because this is an obvious place for third party developers to contribute. It's essentially the entry point into Kill the Cloud as a Platform where application developers can contribute applications for our servers.
This insight simplified implementing managers for each resource class. For example, a manager of file resources, a manager of packages, etc. Having a manager foreach resource class then made it possible to batch updates across an entire change set. They solved a number of problems updating packages in particular, since the removal of a package in one node of a tree didn't strictly mean that the package could now be removed because it may be required elsewhere. Having a package manager that only applied changes at the very end of a transaction meant that we could identify which packages to create, update, and delete by performing two asymmetrical difference operations and one intersection between the old resource set and the new resource set.
@ -69,2 +69,4 @@});});Deno.test('derivePatchedConfig does not change unrelated values', () => {// TODO: Doesn't account for changing application datawhat does this mean?!