doc updates

This commit is contained in:
Jonathan Shook 2023-12-09 17:17:06 -06:00
parent 57129e8968
commit 725a9b5d88

View File

@ -32,21 +32,24 @@
*
* <H2>Components Defined</H2>
* <P>There can be different layers or types of components, but there is only one component hierarchy in each
* NoSQLBench process. Basically the Session is a component. The Scenario is a component. Each activity within a
* scenario is a component. Whether something is meaningful as a component depends on whether the management facilities
* provided by the component API make using, interacting with, or understanding that element better for users. However
* there is a limit to how fine-grained the component hierarchy should be allowed to get. This is because maintaining
* the component structure at runtime incurs a cost, and most feature of the component types are related to assemblage
* of fixtures in the runtime which are configured and initialized before steady state processing begins. For example,
* it makes sense to wire an activity as component, but not an operation, since an operation is ephemeral and
* short-lived. Apart from these trade-offs, make a layer a component layer if it makes sense for the user and/or the
* developer, as consolidating the logic into the component layer is beneficial to both.</P>
* NoSQLBench process. Basically the Session is a component. Each activity container within a session is a component.
* Each activity within a container is a component. Whether something is meaningful as a component depends on whether
* the management facilities provided by the component API make using, interacting with, or understanding that element
* better for users. However there is a limit to how fine-grained the component hierarchy should be allowed to get.
* This
* is because maintaining the component structure at runtime incurs a cost, and most features of the component types
* are
* related to assemblage of fixtures in the runtime which are configured and initialized before steady state processing
* begins. For example, it makes sense to wire an activity as component, but not an operation, since an operation is
* ephemeral and short lived. Apart from these trade-offs, make a layer a component layer if it makes sense for the
* user
* and/or the developer, as consolidating the logic into the component layer is beneficial to both.</P>
*
* <H2>Adoption Strategy</H2>
* <P>Consolidating existing logic to use the component types will be an incremental process. The base contract type
* {@link io.nosqlbench.nb.api.components.NBComponent} establishes the contract for any conforming types. As contract facets
* are added to this type, common logic can be implemented on the base implementation types where possible, allowing
* for the elision of duplicitous code from prior functionality.</P>
* {@link io.nosqlbench.nb.api.components.core.NBComponent} establishes the contract for any conforming types. As
* contract facets are added to this type, common logic can be implemented on the base implementation types where
* possible, allowing for the elision of duplicitous code from prior functionality.</P>
* <p>
* <p>
* <hr/>
@ -56,13 +59,18 @@
*
* <P>Components are structured hierarchically. All components exist within the scope of their parent, with the only
* exception being the root component, which has no parent. Components always know their parent from construction time.
* After a component is constructed, it is informed of children components being added and removed via
* {@link io.nosqlbench.nb.api.components.NBComponent#attachChild} and {@link io.nosqlbench.nb.api.components.NBComponent#detachChild}
* After a component is constructed, it is informed of child components being added and removed via
* {@link io.nosqlbench.nb.api.components.core.NBComponent#attachChild} and
* {@link io.nosqlbench.nb.api.components.core.NBComponent#detachChild}
* methods.</P>
*
* <P>Component logic should interact with other components using the component interfaces and types. No contextual
* typing or casting should be allowed within the component layer methods. Components only understand components by
* design, and breaking this abstraction is counter-productive at best.</P>
* <P>Component-specific logic should interact with other components using the component interfaces and types. No
* contextual typing or casting should be allowed within the component layer methods, except in the case that types
* outside of the component type system are leveraging component layers for features of other non-component types. In
* other words, Component APIs should be thought of as a layer of primitives which sit on top of low-level Java
* primitive, and below those types which use them. Component logic can't understand higher types without breaking the
* seal on a useful abstraction. Components only understand components by design, and breaking this abstraction is
* counter-productive at best.</P>
*
* <P>Utility classes which understand how to interact with components should be used where possible when the
* capabilities they provide are well-themed and cohesive. A Corollary to this is that each interface added to the core
@ -76,21 +84,40 @@
* <H3>Life-cycle Oriented Components</H3>
* <P>Life-cycle components represent executions of some user-managed scope, like session, scenarios, or activities.
* These components model the nesting structure of threads of execution, or for activities, groups of threads. As such,
* any sub-components they have are generally there to augment or contextualize the execution of the life-cycle component.
* In this case, the life-cycle component controls the life-line of its sub-components. When the life-cycle component is
* ready to finish its own execution, it will directly inform all components attached to it that it is time for them
* to do final housekeeping, including any final buffering and sending, connection tear-down, etc. As components, the parent
* component may not know what the details of these housekeeping steps are directly. But components are always something else too,
* and in the type-specific implementations which are triggered by component methods, appropriate integrations can take place.</P>
* any sub-components they have are generally there to augment or contextualize the execution of the life-cycle
* component.</P>
* <P>Life-cycle components may control the life-line of its sub-components. In that case, when the life-cycle
* component
* is ready to finish its own execution, it should directly inform all components attached to it that it is time for
* them to do final housekeeping, including any final buffering and sending, connection tear-down, etc. As components,
* the parent
* component may not know what the details of these housekeeping steps are directly. But components are always
* something else too, and in the type-specific implementations which are triggered by component methods, appropriate
* integrations can take place indirectly through the component API or events.</P>
* <P>In other life-cycle components, the parent component can be thought of as a passive container over child
* components which
* may exit on their own terms. In this case, the parent component should have appropriate eventing and state tracking
* so that
* its life-cycle is properly bounded around the sub components. In other words, it would be a bug if all the sub
* components
* had completed their work and the parent component sat idle in the component hierarchy without completing itself or
* alternately
* sending events to trigger some other life-cycle cleanup. How this is handled is not specific explicitly for all
* components.
* Still, it is a design error to have idle components in the hierarchy with no durable life-cycle cleanup
* mechanism.</P>
*
* <H3>Service Oriented Components</H3>
* <p>Service components are those which are created as an attachment to other components. They may or may not have additional asynchronous
* behavior with respect to their parent component, but they are always in service of the parent component. For example, metrics instruments
* like counters are passive, but reporters which send these metrics outside of the system are active and on a schedule.
* Service-oriented components generally do not control the duration of their lifetimes. When they are working properly, they exist
* along-side and attached to their parent component for the full lifetime of that parent, and then are reaped on demand by the parent
* component.</p>
*
* <p>Service components are those which are created as an attachment to other components. They may or may not have
* additional asynchronous behavior with respect to their parent component, but they are always in service of the parent
* component. For example, metrics instruments like counters are passive, but reporters which send these metrics outside
* of the system are active and on a schedule. Service-oriented components generally do not control the duration of
* their lifetimes. When they are working properly, they exist along-side and attached to their parent component for the
* full lifetime of that parent, and then are reaped on demand by the parent component.</p>
* <P>Ideally reaping of sub-components like this occurs naturally because of standard GC reachability rules. For this to
* work reliably, it is important that you attach components and their children correctly with the component tree, and
* avoid creating extraneous references across unrelated components or across component layers.</P>
* <p>
* <HR/>
* <H2>Labeling Consistency and interlocks</H2>
* TODO: labeling consistency