The counter CRDT is a special type intended for use cases where multiple peers need to increment (or decrement) field values at the same time while maintaining consistency; for example, in scenarios such as inventory management and voting.
There are two methods of modifying an existing counter value:
The counter type is useful in very select scenarios. Consider using the set method to define new values on a map to track increments, while also storing additional metadata.
- Increment — Increases the counter value by the specific number you want to add to the counter value.
- Decrement — Decreases the counter value by the specific negative value that you want to subtract from the counter.
A typical exampe for using a countertype: four flight attendants walk through an airlane and record passenger meal orders. For each seat, they count the number of cans ordered.
First, the flight attendant selects the flight they are on. They then see an interface with each seat in a list view. This might be retrieved by an external API, or it could be internal to the app based on some known information about each plane type.
In a production app, each seat would have a few values that the attendant can modify, but we will just focus on name and orderedCount in this example. As each flight attendant walks through the airplane, their devices synchronize together to make sure that each customer only receives one meal.
If in this case, you used a register type instead of a counter, the value alternates between the latest updated value. Instead, using a counter merges by taking the sum of each attendant's value. If attendant A has sold 100, attendent B has sold 33, and attendant C has sold 98, the value of the counter is 100 + 33 + 98 = 231.
In addition to incrementing counters, you can also decrement a counter .
There is no mechanism preventing a counter from reaching a negative value. For example, if the initial count is 1 and two attendants decrement the count by 1 concurrently, the result is -1.
The following snippet demonstrates code for the typical example for a counter described in Common Use Case, previous.
Ensure the document exists before interacting with it by calling Upsert.
Increment the counter by calling Update.
Do not use Upsert to increment a counter. Incrementing a counter using Upsert results in the counter resetting to its initial value.
This is because when you upsert, you're effectively replacing the entire document with a new one. That is, each field updates, even the document fields that remain unchanged. For more information, see Upserting and Updating.
If you need to perform an upsert at a later time, ensure that your counter value remains consistent by excluding it in your upsert operation.
When the app loads, call populateSeats(), and then renderSeatList().
Since flight attendants keep track of orders, locally populate all known flights with default data.
That way, flight attendants can start collecting information from te beginning, even without an internet connection or any connection with other peers.
Initialize the counter orderedCount by calling DittoCounter().
The totalAvailable variable is stored in a register; therefore, the value remains constant and does not change unless you explicitly make an update to it at a later time.
Render the seat list by incrementing the counter when a user selects the Plus button on the interface.
If you want to notify flight attendants when an item is out of stock and no longer available, compare the number of orders made (orderCount) with the total quantity available (totalAvailable).
If the number of orders equals or exceeds the total available quantity, the app signals that the item is no longer in stock.