com.hazelcast.cp

## Interface CPSubsystem

-     public interface CPSubsystem

  The CP subsystem is a component of a Hazelcast cluster that builds an in-memory strongly consistent layer. It is accessed via `HazelcastInstance.getCPSubsystem()`. Its data structures are CP with respect to the CAP principle, i.e., they always maintain linearizability and prefer consistency over availability during network partitions.

  Currently, the CP subsystem contains only the implementations of Hazelcast's concurrency APIs. These APIs do not maintain large states. For this reason, all members of a Hazelcast cluster do not take part in the CP subsystem. The number of members that takes part in the CP subsystem is specified with `CPSubsystemConfig.setCPMemberCount(int)`. Let's suppose the number of CP members is configured as C. Then, when Hazelcast cluster starts, the first C members form the CP subsystem. These members are called CP members and they can also contain data for other regular Hazelcast data structures, such as `IMap`, `ISet`, etc.

  Data structures in the CP subsystem run in `CPGroup`s. A CP group consists of an odd number of `CPMember`s between 3 and 7. Each CP group independently runs the Raft consensus algorithm. Operations are committed & executed only after they are successfully replicated to the majority of the CP members in a CP group. For instance, in a CP group of 5 CP members, operations are committed when they are replicated to at least 3 CP members. The size of CP groups are specified via `CPSubsystemConfig.setGroupSize(int)` and each CP group contains the same number of CP members.

  Please note that the size of CP groups do not have to be same with the CP member count. Namely, number of CP members in the CP subsystem can be larger than the configured CP group size. In this case, CP groups will be formed by selecting the CP members randomly. Please note that the current CP subsystem implementation works only in memory without persisting any state to disk. It means that a crashed CP member will not be able to recover by reloading its previous state. Therefore, crashed CP members create a danger for gradually losing majority of CP groups and eventually cause the total loss of availability of the CP subsystem. To prevent such situations, failed CP members can be removed from the CP subsystem and replaced in CP groups with other available CP members. This flexibility provides a good degree of fault-tolerance at run-time. Please see `CPSubsystemConfig` and `CPSubsystemManagementService` for more details.

  The CP subsystem runs 2 CP groups by default. The first one is the Metadata group. It is an internal CP group which is responsible for managing the CP members and CP groups. It is be initialized during the cluster startup process if the CP subsystem is enabled via `CPSubsystemConfig.setCPMemberCount(int)` configuration. The second group is the DEFAULT CP group, whose name is given in `CPGroup.DEFAULT_GROUP_NAME`. If a group name is not specified while creating a proxy for a CP data structure, that data structure will be mapped to the DEFAULT CP group. For instance, when a CP `IAtomicLong` instance is created by calling `.getAtomicLong("myAtomicLong")`, it will be initialized on the DEFAULT CP group. Besides these 2 pre-defined CP groups, custom CP groups can be created at run-time. If a CP `IAtomicLong` is created by calling `.getAtomicLong("myAtomicLong@myGroup")`, first a new CP group will be created with the name "myGroup" and then "myAtomicLong" will be initialized on this custom CP group.

  The current set of CP data structures have quite low memory overheads. Moreover, related to the Raft consensus algorithm, each CP group makes uses of internal heartbeat RPCs to maintain authority of the leader member and help lagging CP members to make progress. Last but not least, the new CP lock and semaphore implementations rely on a brand new session mechanism. In a nutshell, a Hazelcast server or a client starts a new session on the corresponding CP group when it makes its very first lock or semaphore acquire request, and then periodically commits session-heartbeats to this CP group to indicate its liveliness. It means that if CP locks and semaphores are distributed into multiple CP groups, there will be a session management overhead. Please see `CPSession` for more details. For the aforementioned reasons, we recommend developers to use a minimal number of CP groups. For most use cases, the DEFAULT CP group should be sufficient to maintain all CP data structure instances. Custom CP groups could be created when throughput of the CP subsystem is needed to be improved.

  The CP subsystem runs a discovery process in the background on cluster startup. When it is enabled by setting a positive value to `CPSubsystemConfig.setCPMemberCount(int)`, say N, the first N members in the cluster member list initiate the discovery process. Other Hazelcast members skip this step. The CP subsystem discovery process runs out of the box on top of Hazelcast's cluster member list without requiring any custom configuration for different environments. It is completed when each one of the first N Hazelcast members initializes its local CP member list and commits it to the Metadata CP group. The Metadata CP group is initialized among those CP members as well. A soon-to-be CP member terminates itself if any of the following conditions occur before the discovery process is completed:

  - Any Hazelcast member leaves the cluster,
  - The local Hazelcast member commits a CP member list which is different from other members' committed CP member lists,
  - The local Hazelcast member list fails to commit its discovered CP member list for any reason.

  When the CP subsystem is restarted via `CPSubsystemManagementService.restart()`, the CP subsystem discovery process is triggered again. However, it does not terminate Hazelcast members if the discovery fails for the aforementioned reasons, because Hazelcast members are likely to contain data for AP data structures and termination can cause data loss. Hence, you need to observe the cluster and check if the discovery process completes successfully on CP subsystem restart. See `CPSubsystemManagementService.restart()` for more details.

  The CP data structure proxies differ from the other Hazelcast data structure proxies in two aspects. First, each time you fetch a proxy via one of the methods in this interface, internally a commit is performed on the Metadata CP group. Hence, callers should cache returned proxies. Second, if you call `DistributedObject.destroy()` on a CP data structure proxy, that data structure is terminated on the underlying CP group and cannot be reinitialized until the CP group is force-destroyed. For this reason, please make sure that you are completely done with a CP data structure before destroying its proxy.

  See Also:
    `CPSubsystemConfig`, `CPMember`, `CPSession`

- - ### Method Summary

    All Methods Instance Methods Abstract Methods
    Modifier and Type | Method and Description
    --- | ---
    `IAtomicLong` | `getAtomicLong(String name)` Returns a proxy for an `IAtomicLong` instance created on the CP subsystem.
    `<E> IAtomicReference<E>` | `getAtomicReference(String name)` Returns a proxy for an `IAtomicReference` instance created on the CP subsystem.
    `ICountDownLatch` | `getCountDownLatch(String name)` Returns a proxy for an `ICountDownLatch` instance created on the CP subsystem.
    `CPSessionManagementService` | `getCPSessionManagementService()` Returns the `CPSessionManagementService` of this Hazelcast instance.
    `CPSubsystemManagementService` | `getCPSubsystemManagementService()` Returns the `CPSubsystemManagementService` of this Hazelcast instance.
    `CPMember` | `getLocalCPMember()` Returns the local CP member if this Hazelcast member is part of the CP subsystem, returns null otherwise.
    `FencedLock` | `getLock(String name)` Returns a proxy for an `FencedLock` instance created on the CP subsystem.
    `ISemaphore` | `getSemaphore(String name)` Returns a proxy for an `ISemaphore` instance created on the CP subsystem.

- - ### Method Detail

    - #### getAtomicLong

          IAtomicLong getAtomicLong(String name)

      Returns a proxy for an `IAtomicLong` instance created on the CP subsystem. Hazelcast's `IAtomicLong` is a distributed version of `java.util.concurrent.atomic.AtomicLong`. If no group name is given within the "name" parameter, then the `IAtomicLong` instance will be created on the DEFAULT CP group. If a group name is given, like `.getAtomicLong("myLong@group1")`, the given group will be initialized first, if not initialized already, and then the `IAtomicLong` instance will be created on this group. Returned `IAtomicLong` instance offers linearizability and behaves as a CP register. When a network partition occurs, proxies that exist on the minority side of its CP group lose availability.

      Each call of this method performs a commit to the Metadata CP group. Hence, callers should cache the returned proxy.

      Parameters:
        `name` - name of the `IAtomicLong` proxy
      Returns:
        `IAtomicLong` proxy for the given name
      Throws:
        `HazelcastException` - if the CP subsystem is not enabled

    - #### getAtomicReference

          <E> IAtomicReference<E> getAtomicReference(String name)

      Returns a proxy for an `IAtomicReference` instance created on the CP subsystem. Hazelcast's `IAtomicReference` is a distributed version of `java.util.concurrent.atomic.AtomicLong`. If no group name is given within the "name" parameter, then the `IAtomicReference` instance will be created on the DEFAULT CP group. If a group name is given, like `.getAtomicReference("myRef@group1")`, the given group will be initialized first, if not initialized already, and then the `IAtomicReference` instance will be created on this group. Returned `IAtomicReference` instance offers linearizability and behaves as a CP register. When a network partition occurs, proxies that exist on the minority side of its CP group lose availability.

      Each call of this method performs a commit to the Metadata CP group. Hence, callers should cache the returned proxy.

      Parameters:
        `name` - name of the `IAtomicReference` proxy
      Returns:
        `IAtomicReference` proxy for the given name
      Throws:
        `HazelcastException` - if the CP subsystem is not enabled

    - #### getCountDownLatch

          ICountDownLatch getCountDownLatch(String name)

      Returns a proxy for an `ICountDownLatch` instance created on the CP subsystem. Hazelcast's `ICountDownLatch` is a distributed version of `java.util.concurrent.CountDownLatch`. If no group name is given within the "name" parameter, then the `ICountDownLatch` instance will be created on the DEFAULT CP group. If a group name is given, like `.getCountDownLatch("myLatch@group1")`, the given group will be initialized first, if not initialized already, and then the `ICountDownLatch` instance will be created on this group. Returned `ICountDownLatch` instance offers linearizability. When a network partition occurs, proxies that exist on the minority side of its CP group lose availability.

      Each call of this method performs a commit to the Metadata CP group. Hence, callers should cache the returned proxy.

      Parameters:
        `name` - name of the `ICountDownLatch` proxy
      Returns:
        `ICountDownLatch` proxy for the given name
      Throws:
        `HazelcastException` - if the CP subsystem is not enabled

    - #### getLock

          FencedLock getLock(String name)

      Returns a proxy for an `FencedLock` instance created on the CP subsystem. Hazelcast's `FencedLock` is a distributed version of `java.util.concurrent.locks.Lock`. If no group name is given within the "name" parameter, then the `FencedLock` instance will be created on the DEFAULT CP group. If a group name is given, like `.getLock("myLock@group1")`, the given group will be initialized first, if not initialized already, and then the `FencedLock` instance will be created on this group. Returned `FencedLock` instance offers linearizability. When a network partition occurs, proxies that exist on the minority side of its CP group lose availability.

      Each call of this method performs a commit to the Metadata CP group. Hence, callers should cache the returned proxy.

      Parameters:
        `name` - name of the `FencedLock` proxy
      Returns:
        `FencedLock` proxy for the given name
      Throws:
        `HazelcastException` - if the CP subsystem is not enabled
      See Also:
        `FencedLockConfig`

    - #### getSemaphore

          ISemaphore getSemaphore(String name)

      Returns a proxy for an `ISemaphore` instance created on the CP subsystem. Hazelcast's `ISemaphore` is a distributed version of `java.util.concurrent.Semaphore`. If no group name is given within the "name" parameter, then the `ISemaphore` instance will be created on the DEFAULT CP group. If a group name is given, like `.getSemaphore("mySemaphore@group1")`, the given group will be initialized first, if not initialized already, and then the `ISemaphore` instance will be created on this group. Returned `ISemaphore` instance offers linearizability. When a network partition occurs, proxies that exist on the minority side of its CP group lose availability.

      Each call of this method performs a commit to the Metadata CP group. Hence, callers should cache the returned proxy.

      Parameters:
        `name` - name of the `ISemaphore` proxy
      Returns:
        `ISemaphore` proxy for the given name
      Throws:
        `HazelcastException` - if the CP subsystem is not enabled
      See Also:
        `CPSemaphoreConfig`

    - #### getLocalCPMember

          CPMember getLocalCPMember()

      Returns the local CP member if this Hazelcast member is part of the CP subsystem, returns null otherwise.

      This method is a shortcut for `CPSubsystemManagementService.getLocalCPMember()` method. Calling this method is equivalent to calling `getCPSubsystemManagementService().getLocalCPMember()`.

      Returns:
        local CP member if available, null otherwise
      Throws:
        `HazelcastException` - if the CP subsystem is not enabled
      See Also:
        `CPSubsystemManagementService.getLocalCPMember()`

    - #### getCPSubsystemManagementService

          CPSubsystemManagementService getCPSubsystemManagementService()

      Returns the `CPSubsystemManagementService` of this Hazelcast instance. `CPSubsystemManagementService` offers APIs for managing CP members and CP groups.
      Returns:
        the `CPSubsystemManagementService` of this Hazelcast instance

    - #### getCPSessionManagementService

          CPSessionManagementService getCPSessionManagementService()

      Returns the `CPSessionManagementService` of this Hazelcast instance. `CPSessionManagementService` offers APIs for managing CP sessions.
      Returns:
        the `CPSessionManagementService` of this Hazelcast instance

Copyright © 2019. All rights reserved.