Home.md
... ...
@@ -59,3 +59,4 @@ try to separate three different aspects.
59 59
- Ecosystem: [[DevEnvironmentLauncherEcosystem]]
60 60
- Gaiwan Stack: [[GaiwanStack/Launchpad]]
61 61
- [[WellKnownIdentifier]] - Predictable commonly used identifiers to access resources
62
+- [[ReloadableComponentSystem]] - Declarative system of components with start/stop/restart and code reloading
ReloadableComponentSystem.md
... ...
@@ -0,0 +1,83 @@
1
+# Reloadable Component System
2
+
3
+## Introduction
4
+
5
+A system consists of components working together. These components need to be
6
+initialized (started) and wired together, and when the system is torn down the
7
+individual components need to be torn down (stopped). The order in which they
8
+are started and stopped depends on the dependencies between the components.
9
+
10
+Components are often stateful, leading to specific concerns when doing
11
+[[Interactive Programming]] against a live process. One needs to resolve issues
12
+arising from stale state, and allow for dynamic reconfiguration and reloading
13
+when in the course of development the system structure or configuration changes.
14
+
15
+## Pattern Description
16
+
17
+In a **Reloadable Component Systems** there are **Components**, which have
18
+`start` and `stop` routines. The start routine accepts configuration and
19
+dependent components, the `stop` routine accepts the previously started
20
+component. These components are assembled and provided configuration values in a
21
+**System Description**.
22
+
23
+The System can then be started as a whole, which will start all components in
24
+topological order, and stopped again, which does a clean shutdown in reverse
25
+topological order.
26
+
27
+A **refresh** or **reset** consists of doing a full code unload/reload in
28
+between stopping the system and restarting it, with the system now freshly
29
+booting from the newly loaded code.
30
+
31
+## Relationship to Dependency Injection
32
+
33
+While Component Systems in Clojure share similarities with, and can be said to
34
+be a type of, dependency injection, they serves a more specialized purpose and
35
+boast a unique history within the Clojure ecosystem.
36
+
37
+Much of this has to do with the dynamic nature of Clojure, and the cultural
38
+preference and excellent affordances for [[Interactive Programming]] (i.e. using
39
+a REPL). This means a system doesn't just need to be able to start up once, it
40
+also needs to be torn down cleanly, restart, receive new configuration while
41
+it's running, and start or stop incrementally (intentionally or because of
42
+failures of certain components to start). Different solutions in the Clojure
43
+space have differing degrees of support for these dynamic use cases.
44
+
45
+Frameworks like Java Spring use XML configuration to declare system and
46
+component structure and dependencies, by providing class names and construction
47
+hints. This is a highly static approach, which doesn't provide support for full
48
+lifecycle management, code reloading, or facilitate dynamic reconfiguration.
49
+
50
+## Alessandra Sierra's Component library and Reloaded Workflow Article
51
+
52
+This pattern and its particular purpose in the context of Clojure was first
53
+described by Alessandra Sierra's, who provided an initial implementation in the
54
+[Component](https://github.com/stuartsierra/component) library, and published
55
+the accompanying [Clojure Workflow Reloaded](https://cognitect.com/blog/2013/06/04/clojure-workflow-reloaded)
56
+article.
57
+
58
+It highlighted the main purpose of a Reloadable Component System: eliminating
59
+stale REPL state.
60
+
61
+> ... some aspects of Clojure's runtime are not quite as late-binding as one might
62
+> wish for interactive development. For example, the effect of a changed macro
63
+> definition will not be seen until code which uses the macro has been
64
+> recompiled. Changes to methods of a defrecord or deftype will not have any
65
+> effect on existing instances of that type.
66
+
67
+Part of the solution is found in
68
+[tools.namespace](https://github.com/clojure/tools.namespace), which allows
69
+reloading a set of namespaces in dependency order. However as Sierra points out
70
+`tools.namespace` alone is not enough. It is also imperative that the version of
71
+the application that's running, and any in-memory state it holds, matches with
72
+version of the application that is encoded in the source files.
73
+
74
+So the proposed approach is to combine tools.namespace with a "component"
75
+(system lifecycle) library. It shuts down the system, removing any stale state,
76
+then reloads all code, and then uses the newly loaded code to construct a new
77
+system state.
78
+
79
+## History
80
+
81
+### 2024-06-10
82
+
83
+- First public version (Ariel Alexis, editing by Arne Brasseur)
SystemLifecycleManagement.md
... ...
@@ -1,80 +0,0 @@
1
-# Managed Component System
2
-
3
-## Introduction
4
-
5
-A system consists of components working together. These components need to be
6
-initialized (started) and wired together, and when the system is torn down the
7
-individual components need to be torn down (stopped). The order in which they
8
-are started and stopped depends on the dependencies between the components.
9
-
10
-Components are often stateful, leading to specific concerns when doing
11
-[[Interactive Programming]] against a live process. One needs to resolve issues
12
-arising from stale state, and allow for dynamic reconfiguration and reloading
13
-when in the course of development the system structure or configuration changes.
14
-
15
-## Pattern Description
16
-
17
-In **System Lifecycle Management** there are **Components**, which have `start`
18
-and `stop` routines. The start routine accepts configuration and dependent
19
-components, the `stop` routine accepts the previously started component. These
20
-components are assembled and provided configuration values in a **System
21
-Description**.
22
-
23
-The **System Description** can then be started as a whole, which will start all
24
-components in topological order.
25
-
26
-Various extensions and variations exist, but these are the key ingredients.
27
-
28
-## Relationship to Dependency Injection
29
-
30
-While system lifecycle management in Clojure shares similarities with, and can
31
-be said to be a type of, dependency injection, it serves a more specialized
32
-purpose and boasts a unique history within the Clojure ecosystem.
33
-
34
-Much of this has to do with the dynamic nature of Clojure, and the cultural
35
-preference and excellent affordances for [[Interactive Programming]] (i.e. using
36
-a REPL). This means a system doesn't just need to be able to start up once, it
37
-also needs to be torn down cleanly, restart, receive new configuration while
38
-it's running, and start or stop incrementally (intentionally or because of
39
-failures of certain components to start). Different solutions in the Clojure
40
-space have differing degrees of support for these dynamic use cases.
41
-
42
-Frameworks like Java Spring use XML configuration to declare system and
43
-component structure and dependencies, by providing class names and construction
44
-hints. This is a highly static approach, which doesn't provide support for full
45
-lifecycle management, or facilitate dynamic reconfiguration.
46
-
47
-## Alessandra Sierra's Component library and Reloaded Workflow Article
48
-
49
-The cultural notion in the Clojure ecosystem of a "component" library and its
50
-purpose originated with Alessandra Sierra's
51
-[Component](https://github.com/stuartsierra/component) library, and the
52
-accompanying [Clojure Workflow Reloaded](https://cognitect.com/blog/2013/06/04/clojure-workflow-reloaded)
53
-article.
54
-
55
-It highlighted the main purpose of system lifecycle management: eliminating
56
-stale REPL state.
57
-
58
-> ... some aspects of Clojure's runtime are not quite as late-binding as one might
59
-> wish for interactive development. For example, the effect of a changed macro
60
-> definition will not be seen until code which uses the macro has been
61
-> recompiled. Changes to methods of a defrecord or deftype will not have any
62
-> effect on existing instances of that type.
63
-
64
-Part of the solution is found in
65
-[tools.namespace](https://github.com/clojure/tools.namespace), which allows
66
-reloading a set of namespaces in dependency order. However as Sierra points out
67
-tools.namespace alone is not enough. It is also imperative that the version of
68
-the application that's running, and any in-memory state it holds, matches with
69
-version of the application that is encoded in the source files.
70
-
71
-So the proposed approach is to combine tools.namespace with a "component"
72
-(system lifecycle) library. It shuts down the system, removing any stale state,
73
-then reloads all code, and then uses the newly loaded code to construct a new
74
-system state.
75
-
76
-## History
77
-
78
-### 2024-06-10
79
-
80
-- First public version (Ariel Alexis, editing by Arne Brasseur)