You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/03/13 10:20:06 UTC
[3/4] incubator-brooklyn git commit: Docs: persistence best practices
/ guidelines
Docs: persistence best practices / guidelines
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fe4668cc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fe4668cc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fe4668cc
Branch: refs/heads/master
Commit: fe4668ccc05eb6e953de1d4172014d63efa462bd
Parents: 4ae4e6a
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 10 17:24:32 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Mar 10 17:24:32 2015 +0000
----------------------------------------------------------------------
docs/guide/ops/persistence/index.md | 75 +++++++++++++++++++++++++-------
1 file changed, 59 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fe4668cc/docs/guide/ops/persistence/index.md
----------------------------------------------------------------------
diff --git a/docs/guide/ops/persistence/index.md b/docs/guide/ops/persistence/index.md
index 1a8fe55..ab8e724 100644
--- a/docs/guide/ops/persistence/index.md
+++ b/docs/guide/ops/persistence/index.md
@@ -250,33 +250,76 @@ Writing Persistable Code
The most common problem on rebind is that custom entity code has not been written in a way
that can be persisted and/or rebound.
-The rule of thumb when implementing new entities, locations and policies is that all state
-must be persistable. All state must be stored as config or as attributes, and must be
-serializable (e.g. avoid the use of anonymous inner classes).
+The rule of thumb when implementing new entities, locations, policies and enrichers is that
+all state must be persistable. All state must be stored as config or as attributes, and must be
+serializable. For making backwards compatibility simpler, the persisted state should be clean.
-Below is a guide for when implementing an entity in Java (or any other JVM language):
+Below are tips and best practices for when implementing an entity in Java (or any other
+JVM language).
-* Don't store state in artibrary fields - the field will not be persisted (this is a design
+How to store entity state:
+
+* Config keys and values are persisted.
+* Store an entity's runtime state as attributes.
+* Don't store state in arbitrary fields - the field will not be persisted (this is a design
decision, because Brooklyn cannot intercept the field being written to, so cannot know
when to persist).
-* Store runtime state as attributes.
+* Don't just modify the retrieved attribute value (e.g. `getAttribute(MY_LIST).add("a")` is bad).
+ The value may not be persisted unless setAttribute() is called.
+* For special cases, it is possible to call `entity.requestPerist()` which will trigger
+ asynchronous persistence of the entity.
+* Overriding (and customizing) of `getRebindSupport()` is discouraged - this will change
+ in a future version.
+
+
+How to store policy/enricher/location state:
+
+* Store values as config keys where applicable.
+* Unfortunately these (currently) do not have attributes. Normally the state of a policy
+ or enricher is transient - on rebind it starts afresh, for example with monitoring the
+ performance or health metrics rather than relying on the persisted values.
+* For special cases, you can annotate a field with `@SetFromFlag` for it be persisted.
+ When you call `requestPersist()` then values of these fields will be scheduled to be
+ persisted. *Warning: the `@SetFromFlag` functionality may change in future versions.*
+
+Persistable state:
+
* Ensure values can be serialized. This (currently) uses xstream, which means it does not
- need to implement `Serializable`. However, if declaring your own classes that are to be
- persisted as state of the entity then declare them as static (or top-level) classes
- rather than anonymous inner classes or non-static inner classes.
+ need to implement `Serializable`.
+* Always use static (or top-level) classes. Otherwise it will try to also persist the outer
+ instance!
+* Any reference to an entity or location will be automatically swapped out for marker, and
+ re-injected with the new entity/location instance on rebind. The same applies for policies,
+ enrichers, feeds, catalog items and `ManagementContext`.
+
+Behaviour on rebind:
+
* By extending `SoftwareProcess`, entities get a lot of the rebind logic for free. For
example, the default `rebind()` method will call `connectSensors()`.
+ See [`SoftwareProcess` Lifecycle]({{site.path.guide}}/java/entities.html#SoftwareProcess-lifecycle)
+ for more details.
* If necessary, implement rebind. The `entity.rebind()` is called automatically by the
Brooklyn framework on rebind, after configuring the entity's config/attributes but before
the entity is managed.
Note that `init()` will not be called on rebind.
-* For special cases, it is possible to call `entity.requestPerist()` which will trigger
- asynchronous persistence of the entity.
-
-For locations, policies and enrichers they (currently) do not have attributes. However,
-config is persisted automatically. Normally the state of a policy or enricher is transient -
-on rebind it starts afresh, for example with monitoring the performance or health metrics
-rather than relying on the persisted values.
+* Feeds will be persisted if and only if `entity.addFeed(...)` was called. Otherwise the
+ feed needs to be re-registered on rebind. *Warning: this behaviour may change in future version.*
+* All functions/predicates used with persisted feeds must themselves be persistable -
+ use of anonymous inner classes is strongly discouraged.
+* Subscriptions (e.g. from calls to `subscribe(...)` for sensor events) are not persisted.
+ They must be re-registered on rebind. *Warning: this behaviour may change in future version.*
+
+Below are tips to make backwards-compatibility easier for persisted state:
+
+* Never use anonymous inner classes - even in static contexts. The auto-generated class names
+ are brittle, making backwards compatibility harder.
+* Always use sensible field names (and use `transient` whenever you don't want it persisted).
+ The field names are part of the persisted state.
+* Consider using Value Objects for persisted values. This can give clearer separation of
+ responsibilities in your code, and clearer control of what fields are being persisted.
+* Consider writing transformers to handle backwards-incompatible code changes.
+ Brooklyn supports applying transformations to the persisted state, which can be done as
+ part of an upgrade process.
Persisted State Backup