Current section
Files
Jump to
Current section
Files
doc/cloudi_crdt.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Module cloudi_crdt</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
</head>
<body bgcolor="white">
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
<hr>
<h1>Module cloudi_crdt</h1>
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>
<h3><a name="CloudI_CRDT_(Conflict-free_Replicated_Data_Type)">CloudI CRDT (Conflict-free Replicated Data Type)</a></h3><p>
This module provides a POLog CRDT implementation with an Erlang map
data type for use in internal CloudI services. Usage of the module
handles the replication of Erlang map state between Erlang processes to
provide an eventually consistent data store among internal CloudI service
processes.</p>.
<p>Copyright © 2017-2020 Michael Truog</p>
<p><b>Version:</b> 2.0.1 Nov 26 2020 15:50:56
------------------------------------------------------------------------</p>
<p><b>Authors:</b> Michael Truog (<a href="mailto:mjtruog at protonmail dot com"><tt>mjtruog at protonmail dot com</tt></a>).</p>
<h2><a name="description">Description</a></h2>
<h3><a name="CloudI_CRDT_(Conflict-free_Replicated_Data_Type)">CloudI CRDT (Conflict-free Replicated Data Type)</a></h3><p>
This module provides a POLog CRDT implementation with an Erlang map
data type for use in internal CloudI services. Usage of the module
handles the replication of Erlang map state between Erlang processes to
provide an eventually consistent data store among internal CloudI service
processes.</p>
<p>The bootstrap functionality and the clean_vclocks functionality are
not described in the POLog papers and are likely unique to this
implementation. This additional functionality allows CloudI service
processes that utilize cloudi_crdt to start, restart or
fail (a crash, netsplit, etc.) without affecting other instances of
cloudi_crdt that are configured with the same service name and
manage the same data.</p>
<p>The cloudi_crdt functions that may be called within
cloudi_service_init/4 are events_subscribe/3, events_subscribe/4,
events_subscriptions/3, events_clear/2, events_clear/3, new/1 and new/2.
A CloudI service that uses cloudi_crdt should have a
destination refresh method that is immediate.</p>
<p>N.B., Any use of an update function or an assign function
requires special attention to ensure the data change is repeatable
for all CRDT instances. The update functions and the assign functions
are not idempotent but can be used safely if the input data is not
unique to a service instance process or service request.
An assign function can cause concurrent assigns to occur for the same
key (e.g., caused by concurrent service requests) and the value
stored in each CRDT instance needs to be the same.
To avoid the problem, data can be added to the CRDT instance
(achieving consistency there) before it is used as data input for
an update function or an assign function. It is important to also
consider using the put function instead of update or assign to avoid
potential consistency problems.</p>
<p>The papers related to this implementation of the POLog CRDT are:</p>
<p>Carlos Baquero, Paulo Sérgio Almeida, Ali Shoker.
Pure Operation-Based Replicated Data Types. 2017.
https://arxiv.org/abs/1710.04469</p>
<p>Georges Younes, Ali Shoker, Paulo Sérgio Almeida, and Carlos Baquero.
Integration Challenges of Pure Operation-based CRDTs in Redis.
In First Workshop on Programming Models and Languages for
Distributed Computing (PMLDC '16). ACM, New York, NY, USA, Article 7, 2016.
http://haslab.uminho.pt/cbm/files/pmldc-2016-redis-crdts.pdf</p>
<p>Carlos Baquero, Paulo Sérgio Almeida, and Ali Shoker.
Making operation-based crdts operation-based.
In Proceedings of the First Workshop on Principles and
Practice of Eventual Consistency, page 7. ACM, 2014.
http://haslab.uminho.pt/ashoker/files/opbaseddais14.pdf</p>
<p>Mattern, Friedemann. "Virtual Time and Global States of
Distributed Systems". Workshop on Parallel and Distributed
Algorithms: pp. 215-226 (1988).
http://homes.cs.washington.edu/~arvind/cs425/doc/mattern89virtual.pdf</p>
Lamport, Leslie. "Time, clocks, and the ordering of events in a
distributed system". Communications of the ACM. 21 (7): 558–565. (1978)
http://research.microsoft.com/en-us/um/people/lamport/pubs/time-clocks.pdf
<h2><a name="types">Data Types</a></h2>
<h3 class="typedecl"><a name="type-bootstrap_state">bootstrap_state()</a></h3>
<p><tt>bootstrap_state() = {VClockAvg::float(), NodeId::<a href="#type-node_id">node_id()</a>, VClock::<a href="#type-vclock">vclock()</a>, VClocks::<a href="#type-vclocks">vclocks()</a>, POLogMode::<a href="#type-polog_mode">polog_mode()</a>, POLog::<a href="#type-polog">polog()</a>, Data::<a href="#type-data">data()</a>}</tt></p>
<h3 class="typedecl"><a name="type-data">data()</a></h3>
<p><tt>data() = #{<a href="#type-key">key()</a> := <a href="#type-value">value()</a>}</tt></p>
<h3 class="typedecl"><a name="type-event_id">event_id()</a></h3>
<p><tt>event_id() = <a href="cloudi_service.html#type-trans_id">cloudi_service:trans_id()</a> | any()</tt></p>
<h3 class="typedecl"><a name="type-event_type">event_type()</a></h3>
<p><tt>event_type() = assign | clear | decr | incr | put | update</tt></p>
<h3 class="typedecl"><a name="type-events">events()</a></h3>
<p><tt>events() = #{<a href="#type-key">key()</a> := [<a href="#type-event_type">event_type()</a>]}</tt></p>
<h3 class="typedecl"><a name="type-initial_data_function">initial_data_function()</a></h3>
<p><tt>initial_data_function() = fun((<a href="#type-data">data()</a>) -> any())</tt></p>
<h3 class="typedecl"><a name="type-key">key()</a></h3>
<p><tt>key() = any()</tt></p>
<h3 class="typedecl"><a name="type-milliseconds">milliseconds()</a></h3>
<p><tt>milliseconds() = 1..4294967295</tt></p>
<h3 class="typedecl"><a name="type-node_id">node_id()</a></h3>
<p><tt>node_id() = {node(), <a href="cloudi_service.html#type-source">cloudi_service:source()</a>}</tt></p>
<h3 class="typedecl"><a name="type-operation_write">operation_write()</a></h3>
<p><tt>operation_write() = {assign, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>} | {incr, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>} | {decr, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>} | {update, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, ModuleVersion::list(), Module::module(), Function::atom()} | {update, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, ModuleVersion::list(), Module::module(), Function::atom(), Argument1::any()} | {update_assign, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, ModuleVersion::list(), Module::module(), Function::atom()} | {update_assign, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, ModuleVersion::list(), Module::module(), Function::atom(), Argument1::any()} | {update_clear, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, ModuleVersion::list(), Module::module(), Function::atom()} | {update_clear, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, ModuleVersion::list(), Module::module(), Function::atom(), Argument1::any()} | {put, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>} | {clear, Id::<a href="#type-event_id">event_id()</a>, Key::<a href="#type-key">key()</a>} | {clear_all, Id::<a href="#type-event_id">event_id()</a>}</tt></p>
<h3 class="typedecl"><a name="type-options">options()</a></h3>
<p><tt>options() = [{service_name, string()} | {init_delay, undefined | <a href="#type-milliseconds">milliseconds()</a>} | {node_count, non_neg_integer()} | {initial_data_function, <a href="#type-initial_data_function">initial_data_function()</a> | undefined} | {clean_vclocks, <a href="#type-seconds">seconds()</a>} | {clean_vclocks_failure, undefined | float() | 1..100} | {retry, non_neg_integer()} | {retry_delay, non_neg_integer()} | {timeout_default, <a href="cloudi_service.html#type-timeout_milliseconds">cloudi_service:timeout_milliseconds()</a>} | {priority_default, <a href="cloudi_service.html#type-priority">cloudi_service:priority()</a>} | {priority_default_offset, -255..255 | undefined}]</tt></p>
<h3 class="typedecl"><a name="type-polog">polog()</a></h3>
<p><tt>polog() = [{<a href="#type-vclock">vclock()</a>, <a href="#type-operation_write">operation_write()</a>}]</tt></p>
<h3 class="typedecl"><a name="type-polog_mode">polog_mode()</a></h3>
<p><tt>polog_mode() = bootstrap | normal</tt></p>
<h3 class="typedecl"><a name="type-seconds">seconds()</a></h3>
<p><tt>seconds() = 1..4294967</tt></p>
<h3 class="typedecl"><a name="type-state">state()</a></h3>
<p><tt>state() = #cloudi_crdt{service_name_full = <a href="cloudi_service.html#type-service_name">cloudi_service:service_name()</a>, init_delay = undefined | <a href="#type-milliseconds">milliseconds()</a>, node_count = non_neg_integer(), initial_data_function = undefined | <a href="#type-initial_data_function">initial_data_function()</a>, clean_vclocks_interval = <a href="#type-seconds">seconds()</a>, clean_vclocks_failure = number(), queue = <a href="cloudi_queue.html#type-state">cloudi_queue:state()</a>, word_size = pos_integer(), node_id = <a href="#type-node_id">node_id()</a>, node_ids = [<a href="#type-node_id">node_id()</a>], vclock = <a href="#type-vclock">vclock()</a>, vclocks = <a href="#type-vclocks">vclocks()</a>, polog_mode = <a href="#type-polog_mode">polog_mode()</a>, bootstrap_node_id = undefined | <a href="#type-node_id">node_id()</a>, bootstrap_states = [<a href="#type-bootstrap_state">bootstrap_state()</a>], bootstrap_requests = non_neg_integer(), polog = <a href="#type-polog">polog()</a>, flush = boolean(), data = <a href="#type-data">data()</a>, events = <a href="#type-events">events()</a>, events_any = [<a href="#type-event_type">event_type()</a>]}</tt></p>
<h3 class="typedecl"><a name="type-value">value()</a></h3>
<p><tt>value() = any()</tt></p>
<h3 class="typedecl"><a name="type-vclock">vclock()</a></h3>
<p><tt>vclock() = #{<a href="#type-node_id">node_id()</a> := non_neg_integer()}</tt></p>
<h3 class="typedecl"><a name="type-vclocks">vclocks()</a></h3>
<p><tt>vclocks() = #{<a href="#type-node_id">node_id()</a> := <a href="#type-vclock">vclock()</a>}</tt></p>
<h2><a name="index">Function Index</a></h2>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#assign-4">assign/4</a></td><td>
<h4><a name="Assign_a_value_iff_none_exists_in_the_CloudI_CRDT.">Assign a value iff none exists in the CloudI CRDT.</a></h4>
If the assign value is not the same value for each
instance of the CloudI CRDT, it can create inconsistencies in
the Erlang map that is used for all read operations
(e.g., if two assigns occur concurrently for the same key with
different values based on two concurrent service requests).</td></tr>
<tr><td valign="top"><a href="#assign_id-5">assign_id/5</a></td><td>
<h4><a name="Assign_a_value_iff_none_exists_in_the_CloudI_CRDT_with_an_event_id.">Assign a value iff none exists in the CloudI CRDT with an event_id.</a></h4>
If the assign value is not the same value for each
instance of the CloudI CRDT, it can create inconsistencies in
the Erlang map that is used for all read operations
(e.g., if two assigns occur concurrently for the same key with
different values based on two concurrent service requests).</td></tr>
<tr><td valign="top"><a href="#byte_size-2">byte_size/2</a></td><td>
<h4><a name="Return_the_size_of_the_CloudI_CRDT_in_bytes.">Return the size of the CloudI CRDT in bytes.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#clear-2">clear/2</a></td><td>
<h4><a name="Clear_the_CloudI_CRDT.">Clear the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#clear-3">clear/3</a></td><td>
<h4><a name="Clear_a_key_in_the_CloudI_CRDT.">Clear a key in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#clear_id-3">clear_id/3</a></td><td>
<h4><a name="Clear_the_CloudI_CRDT_with_an_event_id.">Clear the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#clear_id-4">clear_id/4</a></td><td>
<h4><a name="Clear_a_key_in_the_CloudI_CRDT_with_an_event_id.">Clear a key in the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#crdt_size-1">crdt_size/1</a></td><td>
<h4><a name="Return_the_number_of_CloudI_CRDT_instances.">Return the number of CloudI CRDT instances.</a></h4>
The number of CRDT instances should match the number of write operations.</td></tr>
<tr><td valign="top"><a href="#decr-3">decr/3</a></td><td>
<h4><a name="Decrement_a_numerical_value_by_1_in_the_CloudI_CRDT.">Decrement a numerical value by 1 in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#decr-4">decr/4</a></td><td>
<h4><a name="Decrement_a_numerical_value_in_the_CloudI_CRDT.">Decrement a numerical value in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#decr_id-4">decr_id/4</a></td><td>
<h4><a name="Decrement_a_numerical_value_by_1_in_the_CloudI_CRDT_with_an_event_id.">Decrement a numerical value by 1 in the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#decr_id-5">decr_id/5</a></td><td>
<h4><a name="Decrement_a_numerical_value_in_the_CloudI_CRDT_with_an_event_id.">Decrement a numerical value in the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#events_clear-2">events_clear/2</a></td><td>
<h4><a name="Clear_all_event_subscriptions_from_the_CloudI_CRDT.">Clear all event subscriptions from the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#events_clear-3">events_clear/3</a></td><td>
<h4><a name="Clear_a_subscription_to_events_from_the_CloudI_CRDT.">Clear a subscription to events from the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#events_subscribe-3">events_subscribe/3</a></td><td>
<h4><a name="Subscribe_to_events_from_the_CloudI_CRDT.">Subscribe to events from the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#events_subscribe-4">events_subscribe/4</a></td><td>
<h4><a name="Subscribe_to_specific_events_from_the_CloudI_CRDT.">Subscribe to specific events from the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#events_subscriptions-3">events_subscriptions/3</a></td><td>
<h4><a name="Subscriptions_on_all_keys_to_specific_events_from_the_CloudI_CRDT.">Subscriptions on all keys to specific events from the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#find-3">find/3</a></td><td>
<h4><a name="Find_a_value_in_the_CloudI_CRDT.">Find a value in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#flush_next_write-2">flush_next_write/2</a></td><td>
<h4><a name="Flush_the_next_write_operation_in_the_CloudI_CRDT.">Flush the next write operation in the CloudI CRDT.</a></h4>
Use flush_next_write to ensure the next write operation occurs
as immediately as possible in all processes.</td></tr>
<tr><td valign="top"><a href="#fold-4">fold/4</a></td><td>
<h4><a name="Fold_a_function_over_the_CloudI_CRDT.">Fold a function over the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#get-3">get/3</a></td><td>
<h4><a name="Get_a_value_from_the_CloudI_CRDT.">Get a value from the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#handle_info-3">handle_info/3</a></td><td>
<h4><a name="Handle_all_info_messages_related_to_the_CloudI_CRDT.">Handle all info messages related to the CloudI CRDT.</a></h4>
Must be called from the <code>cloudi_service_handle_info/3</code> callback function.</td></tr>
<tr><td valign="top"><a href="#handle_request-11">handle_request/11</a></td><td>
<h4><a name="Handle_a_CRDT_service_request.">Handle a CRDT service request.</a></h4>
Must be called from the <code>cloudi_service_handle_request/11</code> callback function.</td></tr>
<tr><td valign="top"><a href="#incr-3">incr/3</a></td><td>
<h4><a name="Increment_a_numerical_value_by_1_in_the_CloudI_CRDT.">Increment a numerical value by 1 in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#incr-4">incr/4</a></td><td>
<h4><a name="Increment_a_numerical_value_in_the_CloudI_CRDT.">Increment a numerical value in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#incr_id-4">incr_id/4</a></td><td>
<h4><a name="Increment_a_numerical_value_by_1_in_the_CloudI_CRDT_with_an_event_id.">Increment a numerical value by 1 in the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#incr_id-5">incr_id/5</a></td><td>
<h4><a name="Increment_a_numerical_value_in_the_CloudI_CRDT_with_an_event_id.">Increment a numerical value in the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#is_key-3">is_key/3</a></td><td>
<h4><a name="Check_if_a_key_is_in_the_CloudI_CRDT.">Check if a key is in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#keys-2">keys/2</a></td><td>
<h4><a name="Get_all_keys_in_the_CloudI_CRDT.">Get all keys in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#new-1">new/1</a></td><td>
<h4><a name="Create_a_CloudI_CRDT.">Create a CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#new-2">new/2</a></td><td>
<h4><a name="Create_a_CloudI_CRDT.">Create a CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#put-4">put/4</a></td><td>
<h4><a name="Put_a_value_into_the_CloudI_CRDT.">Put a value into the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#put_id-5">put_id/5</a></td><td>
<h4><a name="Put_a_value_into_the_CloudI_CRDT_with_an_event_id.">Put a value into the CloudI CRDT with an event_id.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#size-2">size/2</a></td><td>
<h4><a name="Get_the_size_of_the_CloudI_CRDT.">Get the size of the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#update-5">update/5</a></td><td>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT.">Update a value iff it exists in the CloudI CRDT.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update-6">update/6</a></td><td>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT.">Update a value iff it exists in the CloudI CRDT.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_assign-6">update_assign/6</a></td><td>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT.">Update a value or assign a value in the CloudI CRDT.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_assign-7">update_assign/7</a></td><td>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT.">Update a value or assign a value in the CloudI CRDT.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_assign_id-7">update_assign_id/7</a></td><td>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or assign a value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_assign_id-8">update_assign_id/8</a></td><td>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or assign a value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_clear-5">update_clear/5</a></td><td>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT.">Update a value or clear the value in the CloudI CRDT.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_clear-6">update_clear/6</a></td><td>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT.">Update a value or clear the value in the CloudI CRDT.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_clear_id-6">update_clear_id/6</a></td><td>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or clear the value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_clear_id-7">update_clear_id/7</a></td><td>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or clear the value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_id-6">update_id/6</a></td><td>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT_with_an_event_id.">Update a value iff it exists in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#update_id-7">update_id/7</a></td><td>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT_with_an_event_id.">Update a value iff it exists in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.</td></tr>
<tr><td valign="top"><a href="#values-2">values/2</a></td><td>
<h4><a name="Get_all_values_in_the_CloudI_CRDT.">Get all values in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#zero-3">zero/3</a></td><td>
<h4><a name="Put_a_zero_value_in_the_CloudI_CRDT.">Put a zero value in the CloudI CRDT.</a></h4>.</td></tr>
<tr><td valign="top"><a href="#zero_id-4">zero_id/4</a></td><td>
<h4><a name="Put_a_zero_value_in_the_CloudI_CRDT_with_an_event_id.">Put a zero value in the CloudI CRDT with an event_id.</a></h4>.</td></tr>
</table>
<h2><a name="functions">Function Details</a></h2>
<h3 class="function"><a name="assign-4">assign/4</a></h3>
<div class="spec">
<p><tt>assign(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Assign_a_value_iff_none_exists_in_the_CloudI_CRDT.">Assign a value iff none exists in the CloudI CRDT.</a></h4>
If the assign value is not the same value for each
instance of the CloudI CRDT, it can create inconsistencies in
the Erlang map that is used for all read operations
(e.g., if two assigns occur concurrently for the same key with
different values based on two concurrent service requests).</p>
<h3 class="function"><a name="assign_id-5">assign_id/5</a></h3>
<div class="spec">
<p><tt>assign_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Assign_a_value_iff_none_exists_in_the_CloudI_CRDT_with_an_event_id.">Assign a value iff none exists in the CloudI CRDT with an event_id.</a></h4>
If the assign value is not the same value for each
instance of the CloudI CRDT, it can create inconsistencies in
the Erlang map that is used for all read operations
(e.g., if two assigns occur concurrently for the same key with
different values based on two concurrent service requests).</p>
<h3 class="function"><a name="byte_size-2">byte_size/2</a></h3>
<div class="spec">
<p><tt>byte_size(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> non_neg_integer()</tt><br></p>
</div><p>
<h4><a name="Return_the_size_of_the_CloudI_CRDT_in_bytes.">Return the size of the CloudI CRDT in bytes.</a></h4>
</p>
<h3 class="function"><a name="clear-2">clear/2</a></h3>
<div class="spec">
<p><tt>clear(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Clear_the_CloudI_CRDT.">Clear the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="clear-3">clear/3</a></h3>
<div class="spec">
<p><tt>clear(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Clear_a_key_in_the_CloudI_CRDT.">Clear a key in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="clear_id-3">clear_id/3</a></h3>
<div class="spec">
<p><tt>clear_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Clear_the_CloudI_CRDT_with_an_event_id.">Clear the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="clear_id-4">clear_id/4</a></h3>
<div class="spec">
<p><tt>clear_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Clear_a_key_in_the_CloudI_CRDT_with_an_event_id.">Clear a key in the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="crdt_size-1">crdt_size/1</a></h3>
<div class="spec">
<p><tt>crdt_size(Cloudi_crdt::<a href="#type-state">state()</a>) -> pos_integer()</tt><br></p>
</div><p>
<h4><a name="Return_the_number_of_CloudI_CRDT_instances.">Return the number of CloudI CRDT instances.</a></h4>
The number of CRDT instances should match the number of write operations.</p>
<h3 class="function"><a name="decr-3">decr/3</a></h3>
<div class="spec">
<p><tt>decr(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Decrement_a_numerical_value_by_1_in_the_CloudI_CRDT.">Decrement a numerical value by 1 in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="decr-4">decr/4</a></h3>
<div class="spec">
<p><tt>decr(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::number(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Decrement_a_numerical_value_in_the_CloudI_CRDT.">Decrement a numerical value in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="decr_id-4">decr_id/4</a></h3>
<div class="spec">
<p><tt>decr_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Decrement_a_numerical_value_by_1_in_the_CloudI_CRDT_with_an_event_id.">Decrement a numerical value by 1 in the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="decr_id-5">decr_id/5</a></h3>
<div class="spec">
<p><tt>decr_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::number(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Decrement_a_numerical_value_in_the_CloudI_CRDT_with_an_event_id.">Decrement a numerical value in the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="events_clear-2">events_clear/2</a></h3>
<div class="spec">
<p><tt>events_clear(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Clear_all_event_subscriptions_from_the_CloudI_CRDT.">Clear all event subscriptions from the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="events_clear-3">events_clear/3</a></h3>
<div class="spec">
<p><tt>events_clear(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Clear_a_subscription_to_events_from_the_CloudI_CRDT.">Clear a subscription to events from the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="events_subscribe-3">events_subscribe/3</a></h3>
<div class="spec">
<p><tt>events_subscribe(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Subscribe_to_events_from_the_CloudI_CRDT.">Subscribe to events from the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="events_subscribe-4">events_subscribe/4</a></h3>
<div class="spec">
<p><tt>events_subscribe(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, EventTypes::[<a href="#type-event_type">event_type()</a>], State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Subscribe_to_specific_events_from_the_CloudI_CRDT.">Subscribe to specific events from the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="events_subscriptions-3">events_subscriptions/3</a></h3>
<div class="spec">
<p><tt>events_subscriptions(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, EventTypes::[<a href="#type-event_type">event_type()</a>], State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Subscriptions_on_all_keys_to_specific_events_from_the_CloudI_CRDT.">Subscriptions on all keys to specific events from the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="find-3">find/3</a></h3>
<div class="spec">
<p><tt>find(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> {ok, Value::<a href="#type-value">value()</a>} | error</tt><br></p>
</div><p>
<h4><a name="Find_a_value_in_the_CloudI_CRDT.">Find a value in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="flush_next_write-2">flush_next_write/2</a></h3>
<div class="spec">
<p><tt>flush_next_write(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Flush_the_next_write_operation_in_the_CloudI_CRDT.">Flush the next write operation in the CloudI CRDT.</a></h4>
Use flush_next_write to ensure the next write operation occurs
as immediately as possible in all processes. When write operations
occur without flush_next_write, process communication is minimized and
write operation completion may depend on the next write operation
function call.</p>
<h3 class="function"><a name="fold-4">fold/4</a></h3>
<div class="spec">
<p><tt>fold(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, F::fun((Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, AccIn::any()) -> AccOut::any()), AccInit::any(), State::<a href="#type-state">state()</a>) -> AccFinal::any()</tt><br></p>
</div><p>
<h4><a name="Fold_a_function_over_the_CloudI_CRDT.">Fold a function over the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="get-3">get/3</a></h3>
<div class="spec">
<p><tt>get(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> Value::<a href="#type-value">value()</a></tt><br></p>
</div><p>
<h4><a name="Get_a_value_from_the_CloudI_CRDT.">Get a value from the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="handle_info-3">handle_info/3</a></h3>
<div class="spec">
<p><tt>handle_info(Request::any(), State::<a href="#type-state">state()</a>, Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>) -> {ok, StateNew::<a href="#type-state">state()</a>} | {{error, Reason::<a href="cloudi_service.html#type-error_reason">cloudi_service:error_reason()</a>}, StateNew::<a href="#type-state">state()</a>} | {ignored, State::<a href="#type-state">state()</a>}</tt><br></p>
</div><p>
<h4><a name="Handle_all_info_messages_related_to_the_CloudI_CRDT.">Handle all info messages related to the CloudI CRDT.</a></h4>
Must be called from the <code>cloudi_service_handle_info/3</code> callback function.</p>
<h3 class="function"><a name="handle_request-11">handle_request/11</a></h3>
<div class="spec">
<p><tt>handle_request(RequestType::<a href="cloudi_service.html#type-request_type">cloudi_service:request_type()</a>, Name::<a href="cloudi_service.html#type-service_name">cloudi_service:service_name()</a>, Pattern::<a href="cloudi_service.html#type-service_name_pattern">cloudi_service:service_name_pattern()</a>, RequestInfo::<a href="cloudi_service.html#type-request_info">cloudi_service:request_info()</a>, Request::<a href="cloudi_service.html#type-request">cloudi_service:request()</a>, Timeout::<a href="cloudi_service.html#type-timeout_value_milliseconds">cloudi_service:timeout_value_milliseconds()</a>, Priority::<a href="cloudi_service.html#type-priority_value">cloudi_service:priority_value()</a>, TransId::<a href="cloudi_service.html#type-trans_id">cloudi_service:trans_id()</a>, Pid::<a href="cloudi_service.html#type-source">cloudi_service:source()</a>, State::<a href="#type-state">state()</a>, Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>) -> {ok, StateNew::<a href="#type-state">state()</a>} | {ignored, State::<a href="#type-state">state()</a>}</tt><br></p>
</div><p>
<h4><a name="Handle_a_CRDT_service_request.">Handle a CRDT service request.</a></h4>
Must be called from the <code>cloudi_service_handle_request/11</code> callback function.</p>
<h3 class="function"><a name="incr-3">incr/3</a></h3>
<div class="spec">
<p><tt>incr(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Increment_a_numerical_value_by_1_in_the_CloudI_CRDT.">Increment a numerical value by 1 in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="incr-4">incr/4</a></h3>
<div class="spec">
<p><tt>incr(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::number(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Increment_a_numerical_value_in_the_CloudI_CRDT.">Increment a numerical value in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="incr_id-4">incr_id/4</a></h3>
<div class="spec">
<p><tt>incr_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Increment_a_numerical_value_by_1_in_the_CloudI_CRDT_with_an_event_id.">Increment a numerical value by 1 in the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="incr_id-5">incr_id/5</a></h3>
<div class="spec">
<p><tt>incr_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::number(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Increment_a_numerical_value_in_the_CloudI_CRDT_with_an_event_id.">Increment a numerical value in the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="is_key-3">is_key/3</a></h3>
<div class="spec">
<p><tt>is_key(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> boolean()</tt><br></p>
</div><p>
<h4><a name="Check_if_a_key_is_in_the_CloudI_CRDT.">Check if a key is in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="keys-2">keys/2</a></h3>
<div class="spec">
<p><tt>keys(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> [<a href="#type-key">key()</a>]</tt><br></p>
</div><p>
<h4><a name="Get_all_keys_in_the_CloudI_CRDT.">Get all keys in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="new-1">new/1</a></h3>
<div class="spec">
<p><tt>new(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Create_a_CloudI_CRDT.">Create a CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="new-2">new/2</a></h3>
<div class="spec">
<p><tt>new(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Options::<a href="#type-options">options()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Create_a_CloudI_CRDT.">Create a CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="put-4">put/4</a></h3>
<div class="spec">
<p><tt>put(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Put_a_value_into_the_CloudI_CRDT.">Put a value into the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="put_id-5">put_id/5</a></h3>
<div class="spec">
<p><tt>put_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Put_a_value_into_the_CloudI_CRDT_with_an_event_id.">Put a value into the CloudI CRDT with an event_id.</a></h4>
</p>
<h3 class="function"><a name="size-2">size/2</a></h3>
<div class="spec">
<p><tt>size(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> non_neg_integer()</tt><br></p>
</div><p>
<h4><a name="Get_the_size_of_the_CloudI_CRDT.">Get the size of the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="update-5">update/5</a></h3>
<div class="spec">
<p><tt>update(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT.">Update a value iff it exists in the CloudI CRDT.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update-6">update/6</a></h3>
<div class="spec">
<p><tt>update(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), Argument1::any(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT.">Update a value iff it exists in the CloudI CRDT.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update_assign-6">update_assign/6</a></h3>
<div class="spec">
<p><tt>update_assign(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, Module::module(), Function::atom(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT.">Update a value or assign a value in the CloudI CRDT.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update_assign-7">update_assign/7</a></h3>
<div class="spec">
<p><tt>update_assign(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, Module::module(), Function::atom(), Argument1::any(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT.">Update a value or assign a value in the CloudI CRDT.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update_assign_id-7">update_assign_id/7</a></h3>
<div class="spec">
<p><tt>update_assign_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, Module::module(), Function::atom(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or assign a value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update_assign_id-8">update_assign_id/8</a></h3>
<div class="spec">
<p><tt>update_assign_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Value::<a href="#type-value">value()</a>, Module::module(), Function::atom(), Argument1::any(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_assign_a_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or assign a value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update_clear-5">update_clear/5</a></h3>
<div class="spec">
<p><tt>update_clear(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT.">Update a value or clear the value in the CloudI CRDT.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).
To clear the value, the function must return undefined.</p>
<h3 class="function"><a name="update_clear-6">update_clear/6</a></h3>
<div class="spec">
<p><tt>update_clear(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), Argument1::any(), State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT.">Update a value or clear the value in the CloudI CRDT.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).
To clear the value, the function must return undefined.</p>
<h3 class="function"><a name="update_clear_id-6">update_clear_id/6</a></h3>
<div class="spec">
<p><tt>update_clear_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or clear the value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).
To clear the value, the function must return undefined.</p>
<h3 class="function"><a name="update_clear_id-7">update_clear_id/7</a></h3>
<div class="spec">
<p><tt>update_clear_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), Argument1::any(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_or_clear_the_value_in_the_CloudI_CRDT_with_an_event_id.">Update a value or clear the value in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).
To clear the value, the function must return undefined.</p>
<h3 class="function"><a name="update_id-6">update_id/6</a></h3>
<div class="spec">
<p><tt>update_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT_with_an_event_id.">Update a value iff it exists in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/1 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="update_id-7">update_id/7</a></h3>
<div class="spec">
<p><tt>update_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Module::module(), Function::atom(), Argument1::any(), Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Update_a_value_iff_it_exists_in_the_CloudI_CRDT_with_an_event_id.">Update a value iff it exists in the CloudI CRDT with an event_id.</a></h4>
Function Module:Function/2 must exist with the same version
for every CloudI service process that shares this CloudI CRDT.
If the function does not execute to return the same result
(when given the same value) for each instance of the CloudI CRDT,
it can create inconsistencies in the Erlang map that is used for
all read operations
(inconsistencies which would only be resolvable manually).</p>
<h3 class="function"><a name="values-2">values/2</a></h3>
<div class="spec">
<p><tt>values(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, State::<a href="#type-state">state()</a>) -> [<a href="#type-value">value()</a>]</tt><br></p>
</div><p>
<h4><a name="Get_all_values_in_the_CloudI_CRDT.">Get all values in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="zero-3">zero/3</a></h3>
<div class="spec">
<p><tt>zero(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Put_a_zero_value_in_the_CloudI_CRDT.">Put a zero value in the CloudI CRDT.</a></h4>
</p>
<h3 class="function"><a name="zero_id-4">zero_id/4</a></h3>
<div class="spec">
<p><tt>zero_id(Dispatcher::<a href="cloudi_service.html#type-dispatcher">cloudi_service:dispatcher()</a>, Key::<a href="#type-key">key()</a>, Id::<a href="#type-event_id">event_id()</a>, State::<a href="#type-state">state()</a>) -> <a href="#type-state">state()</a></tt><br></p>
</div><p>
<h4><a name="Put_a_zero_value_in_the_CloudI_CRDT_with_an_event_id.">Put a zero value in the CloudI CRDT with an event_id.</a></h4>
</p>
<hr>
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
<p><i>Generated by EDoc</i></p>
</body>
</html>