public class AtomicCounterEditor extends DefaultEditor
Manages a node as Atomic Counter: a node which will handle at low level a protected
property (PROP_COUNTER
) in an atomic way. This will represent an increment or decrement
of a counter in the case, for example, of Likes or Voting.
Whenever you add a NodeTypeConstants.MIX_ATOMIC_COUNTER
mixin to a node it will turn it
into an atomic counter. Then in order to increment or decrement the oak:counter
property
you'll need to set the oak:increment
one (PROP_INCREMENT
). Please note that the
oak:incremement
will never be saved, only the oak:counter
will
be amended accordingly.
So in order to deal with the counter from a JCR point of view you'll do something as follows
Session session = ... // creating a counter node Node counter = session.getRootNode().addNode("mycounter"); counter.addMixin("mix:atomicCounter"); // or use the NodeTypeConstants session.save(); // Will output 0. the default value System.out.println("counter now: " + counter.getProperty("oak:counter").getLong()); // incrementing by 5 the counter counter.setProperty("oak:increment", 5); session.save(); // Will output 5 System.out.println("counter now: " + counter.getProperty("oak:counter").getLong()); // decreasing by 1 counter.setProperty("oak:increment", -1); session.save(); // Will output 4 System.out.println("counter now: " + counter.getProperty("oak:counter").getLong()); session.logout();
The related jira ticket is OAK-2472.
In a nutshell when you save an oak:increment
behind the scene it takes its value and
increment an internal counter. There will be an individual counter for each cluster node.
Then it will consolidate all the internal counters into a single one: oak:counter
. The
consolidation process can happen either synchronously or asynchronously. Refer to
AtomicCounterEditor(NodeBuilder, String, ScheduledExecutorService, NodeStore, Whiteboard)
for details on when it consolidate one way or the other.
synchronous. It means the consolidation, sum of all the internal counters, will happen in the same thread. During the lifecycle of the same commit.
asynchronous. It means the internal counters will be set during the same commit; but it will eventually schedule a separate thread in which will retry some times to consolidate them.
Modifier and Type | Class and Description |
---|---|
static class |
AtomicCounterEditor.ConsolidatorTask |
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
PREFIX_PROP_COUNTER
prefix used internally for tracking the counting requests
|
static java.lang.String |
PREFIX_PROP_REVISION
prefix used internally for tracking the cluster node related revision numbers
|
static java.lang.String |
PROP_COUNTER
property with the consolidated counter
|
static java.lang.String |
PROP_INCREMENT
property to be set for incrementing/decrementing the counter
|
INSTANCE
Constructor and Description |
---|
AtomicCounterEditor(NodeBuilder builder,
java.lang.String instanceId,
java.util.concurrent.ScheduledExecutorService executor,
NodeStore store,
Whiteboard board)
Create an instance of the editor for atomic increments.
|
Modifier and Type | Method and Description |
---|---|
Editor |
childNodeAdded(java.lang.String name,
NodeState after)
Processes an added child node.
|
Editor |
childNodeChanged(java.lang.String name,
NodeState before,
NodeState after)
Processes a changed child node.
|
static void |
consolidateCount(NodeBuilder builder)
consolidate the
PREFIX_PROP_COUNTER properties and sum them into the
PROP_COUNTER |
void |
leave(NodeState before,
NodeState after)
Called after the given before and after states are compared.
|
void |
propertyAdded(PropertyState after)
Processes an added property.
|
childNodeDeleted, enter, propertyChanged, propertyDeleted
public static final java.lang.String PROP_INCREMENT
public static final java.lang.String PROP_COUNTER
public static final java.lang.String PREFIX_PROP_COUNTER
public static final java.lang.String PREFIX_PROP_REVISION
public AtomicCounterEditor(NodeBuilder builder, java.lang.String instanceId, java.util.concurrent.ScheduledExecutorService executor, NodeStore store, Whiteboard board)
Create an instance of the editor for atomic increments. It can works synchronously as well as asynchronously. See class javadoc for details around it.
If instanceId
OR executor
OR store
OR board
are null, the
editor will switch to synchronous behaviour for consolidation. If no CommitHook
will
be found in the whiteboard, a EmptyHook
will be provided to the NodeStore
for
merging.
builder
- the build on which to work. Cannot be null.instanceId
- the current Oak instance Id. If null editor will be synchronous.executor
- the current Oak executor service. If null editor will be synchronous.store
- the current Oak node store. If null the editor will be synchronous.board
- the current Oak Whiteboard
.public static void consolidateCount(NodeBuilder builder)
consolidate the PREFIX_PROP_COUNTER
properties and sum them into the
PROP_COUNTER
The passed in NodeBuilder
must have
JCR_MIXINTYPES
with
MIX_ATOMIC_COUNTER
.
If not it will be silently ignored.
builder
- the builder to work on. Cannot be null.public void propertyAdded(PropertyState after) throws CommitFailedException
Editor
propertyAdded
in interface Editor
propertyAdded
in class DefaultEditor
after
- the added propertyCommitFailedException
- if processing failedpublic Editor childNodeAdded(java.lang.String name, NodeState after) throws CommitFailedException
Editor
childNodeAdded
in interface Editor
childNodeAdded
in class DefaultEditor
name
- name of the added nodeafter
- the added child nodenull
if the subtree does not need processingCommitFailedException
- if processing failedpublic Editor childNodeChanged(java.lang.String name, NodeState before, NodeState after) throws CommitFailedException
Editor
childNodeChanged
in interface Editor
childNodeChanged
in class DefaultEditor
name
- name of the changed nodebefore
- child node before the changeafter
- child node after the changenull
if the subtree does not need processingCommitFailedException
- if processing failedpublic void leave(NodeState before, NodeState after) throws CommitFailedException
Editor
leave
in interface Editor
leave
in class DefaultEditor
before
- before state, non-existent if this node was addedafter
- after state, non-existent if this node was removedCommitFailedException
- if this commit should be rejected"Copyright © 2010 - 2019 Adobe Systems Incorporated. All Rights Reserved"