Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New recipe: group membership #13

Open
morphy76 opened this issue Sep 24, 2022 · 1 comment · May be fixed by #15
Open

New recipe: group membership #13

morphy76 opened this issue Sep 24, 2022 · 1 comment · May be fixed by #15
Assignees
Labels
draft The issue is not yet properly defined enhancement New feature or request
Milestone

Comments

@morphy76
Copy link
Contributor

morphy76 commented Sep 24, 2022

New feature, optional at build time, to add group membership for the given runtime.

Group membership enables a shared, per-group, data node where members can perform r/w operations:

  • As a member of a group, I want to load all the shared values so that having an initial view (cache) on the group status;
  • As a member of a group, I want to write/update a value, identified by a key, so that sharing it across all the other members;
  • As a member of a group, I want to be notified on shared data changes, so that having an updated view on the group status.

Newly available API:

@ApplicationScoped
public interface MembershipStatus {
    /**
     * Put a value, identified by the key, into the group status. It performs a
     * version test (optimistic lock) raising a runtime exception if the test fails.
     * 
     * @param value the value to write.
     * @param key   the key which identifies the value.
     * @return an optional array of bytes representing the previous data; an empty
     *         optional if the key has been just created.
     */
    Optional<byte[]> put(byte[] value, String key);

    /**
     * Get a value, identified by the key, from the group status. It refreshes the
     * data version accordingly to the read value.
     * 
     * @param key the key which identifies the value.
     * @return an optional array of bytes representing the data; an empty optional
     *         if the key does not identifies any value within the group status.
     */
    Optional<byte[]> get(String key);

    /**
     * Removes a value, identified by the key, from the group status. It also reset
     * the data version for the given key.
     * 
     * @param key the key which identifies the value.
     * @return an optional array of bytes representing the data; an empty optional
     *         if the key does not identifies any value within the group status.
     */
    Optional<byte[]> clear(String key);

    /**
     * Reads all the keys available within the group status.
     * 
     * @return the set of the keys.
     */
    Set<String> keys();

    /**
     *  An iterator over the group status entries.
     * 
     * @return the iterator.
     */
    Iterator<Map.Entry<String, byte[]>> iterator();
}

@ApplicationScoped
public interface ReactiveMembershipStatus {
    /**
     * Put a value, identified by the key, into the group status. It performs a
     * version test (optimistic lock) raising a runtime exception if the test fails.
     * 
     * @param value the value to write.
     * @param key   the key which identifies the value.
     * @return the action to put a value within the group status holding a null item
     *         if the key has been just created.
     */
    Uni<byte[]> put(byte[] value, String key);

    /**
     * Get a value, identified by the key, from the group status. It refreshes the
     * data version accordingly to the read value.
     * 
     * @param key the key which identifies the value.
     * @return the action to put a value within the group status holding a null item
     *         if the key does not identifies any value within the group status.
     */
    Uni<byte[]> get(String key);

    /**
     * Removes a value, identified by the key, from the group status. It also reset
     * the data version for the given key.
     * 
     * @param key the key which identifies the value.
     * @return the action to put a value within the group status holding a null item
     *         if the key does not identifies any value within the group status.
     */
    Uni<byte[]> clear(String key);

    /**
     * Reads all the keys available within the group status.
     * 
     * @return the action to retrieve the set of the keys.
     */
    Uni<Set<String>> keys();

    /**
     *  A stream of groups status entries..
     * 
     * @return the stream of the entries.
     */
    Multi<Map.Entry<String, byte[]>> entries();
}

Newly available CDI events:

/**
 * Async CDI event to notify changes within the group status
 */
public interface StatusChanged {

    /**
     * The new value set.
     * 
     * @return an optional representing the newly set value, an empty optional if
     *         the key is not available within the group status, anymore.
     */
    Optional<byte[]> getNewValue();

    /**
     * The previous value.
     * 
     * @return an optional representing the previously set value, an empty optional
     *         if the key wasn't previously available within the group status.
     */
    Optional<byte[]> getPreviousValue();

    /**
     * The key associated to the change.
     * 
     * @return the key.
     */
    String getKey();
}

The following new configuration properties are given:

  • quarkus.zookeeper.recipe.membership.enable to enable group membership at build time
  • quarkus.zookeeper.recipe.membership.group-id if membership is enabled, a mandatory string property to specify the group to join
  • quarkus.zookeeper.recipe.membership.namespace if membership is enabled, a mandatory string property to specify the zookeeper root node to store the groups, default value is groups

This enhancement is the prerequisite for another recipe, namely leader election.

@morphy76 morphy76 added enhancement New feature or request draft The issue is not yet properly defined labels Sep 24, 2022
@morphy76
Copy link
Contributor Author

Do not prevent #2

@morphy76 morphy76 added this to the 1.0.2 milestone Sep 24, 2022
@morphy76 morphy76 self-assigned this Sep 24, 2022
@morphy76 morphy76 linked a pull request Sep 25, 2022 that will close this issue
@morphy76 morphy76 linked a pull request Sep 25, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
draft The issue is not yet properly defined enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant