Fixed build

This commit is contained in:
Jaime Freire
2023-11-25 08:18:02 +01:00
parent db9bb4ccdf
commit 789a5f6abc
141 changed files with 3259 additions and 2957 deletions

View File

@ -1,12 +1,15 @@
# Gossip ![Build status](https://travis-ci.org/edwardcapriolo/incubator-gossip.svg?) # Gossip ![Build status](https://travis-ci.org/edwardcapriolo/incubator-gossip.svg?)
Gossip protocol is a method for a group of nodes to discover and check the liveliness of a cluster. More information can be found at http://en.wikipedia.org/wiki/Gossip_protocol. Gossip protocol is a method for a group of nodes to discover and check the liveliness of a cluster. More information can
be found at http://en.wikipedia.org/wiki/Gossip_protocol.
The original implementation was forked from https://code.google.com/p/java-gossip/. Several bug fixes and changes have already been added. The original implementation was forked from https://code.google.com/p/java-gossip/. Several bug fixes and changes have
already been added.
A set of easily-run examples, illustrating various features of Gossip, are available in the gossip-examples module. The README.md file, in that module described how to run those examples. A set of easily-run examples, illustrating various features of Gossip, are available in the gossip-examples module. The
README.md file, in that module described how to run those examples.
Below, a list of code snippits which show how to incorproate Apache Gossip into your project. Below, a list of code snippits which show how to incorproate Apache Gossip into your project.
Usage Usage
----- -----
@ -23,7 +26,8 @@ To gossip you need one or more seed nodes. Seed is just a list of places to init
} }
``` ```
Here we start five gossip processes and check that they discover each other. (Normally these are on different hosts but here we give each process a distinct local ip. Here we start five gossip processes and check that they discover each other. (Normally these are on different hosts but
here we give each process a distinct local ip.
```java ```java
List<GossipService> clients = new ArrayList<>(); List<GossipService> clients = new ArrayList<>();
@ -64,7 +68,7 @@ For a very simple client setup with a settings file you first need a JSON file s
where: where:
* `cluster` - is the name of the cluster * `cluster` - is the name of the cluster
* `id` - is a unique id for this node (you can use any string, but above we use a UUID) * `id` - is a unique id for this node (you can use any string, but above we use a UUID)
* `uri` - is a URI object containing IP/hostname and port to use on the default adapter on the node's machine * `uri` - is a URI object containing IP/hostname and port to use on the default adapter on the node's machine
* `gossip_interval` - how often (in milliseconds) to gossip list of members to other node(s) * `gossip_interval` - how often (in milliseconds) to gossip list of members to other node(s)

View File

@ -1,30 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12"> <profiles version="12">
<profile kind="CodeFormatterProfile" name="Apache UIMA Code Conventions" version="12"> <profile kind="CodeFormatterProfile" name="Apache UIMA Code Conventions" version="12">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/> <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/> <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/> <setting
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/> id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/> <setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="4"/> <setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
@ -36,256 +44,349 @@
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/> <setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/> <setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/> <setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/> <setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/> <setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/> <setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/> value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/> value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/> value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/> <setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters"
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/> <setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement"
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/> <setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/> <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/> <setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/> <setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/> value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/> <setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/> <setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/> value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/> <setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/> value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/> <setting
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/> id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement"
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/> <setting
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/> id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/> value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
</profile> value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles> </profiles>

View File

@ -16,70 +16,51 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.apache.gossip</groupId> <groupId>org.apache.gossip</groupId>
<artifactId>gossip-parent</artifactId> <artifactId>gossip-parent</artifactId>
<version>0.1.3-incubating-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Gossip Base</name>
<artifactId>gossip-base</artifactId>
<version>0.1.3-incubating-SNAPSHOT</version> <version>0.1.3-incubating-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent> <dependencies>
<dependency>
<name>Gossip Base</name> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>gossip-base</artifactId> <artifactId>jackson-core</artifactId>
<version>0.1.3-incubating-SNAPSHOT</version> <version>${jackson.version}</version>
</dependency>
<dependencies> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>org.apache.commons</groupId>
<artifactId>jackson-core</artifactId> <artifactId>commons-math3</artifactId>
<version>${jackson.version}</version> <version>3.6.1</version>
</dependency> </dependency>
<dependency>
<groupId>commons-math</groupId> <dependency>
<artifactId>commons-math</artifactId> <groupId>com.fasterxml.jackson.core</groupId>
<version>${commons-math.version}</version> <artifactId>jackson-databind</artifactId>
</dependency> <version>${jackson.version}</version>
<dependency> </dependency>
<groupId>com.fasterxml.jackson.core</groupId> <dependency>
<artifactId>jackson-databind</artifactId> <groupId>io.dropwizard.metrics</groupId>
<version>${jackson.version}</version> <artifactId>metrics-core</artifactId>
</dependency> <version>${metrics.version}</version>
<dependency> </dependency>
<groupId>io.dropwizard.metrics</groupId> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<artifactId>metrics-core</artifactId> <dependency>
<version>${metrics.version}</version></dependency> <groupId>org.apache.logging.log4j</groupId>
<dependency> <artifactId>log4j-core</artifactId>
<groupId>log4j</groupId> <version>2.22.0</version>
<artifactId>log4j</artifactId> </dependency>
<version>${log4j.version}</version> </dependencies>
<type>jar</type>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>

View File

@ -17,10 +17,9 @@
*/ */
package org.apache.gossip; package org.apache.gossip;
import org.apache.gossip.lock.LockManagerSettings;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.gossip.lock.LockManagerSettings;
/** /**
* In this object the settings used by the GossipService are held. * In this object the settings used by the GossipService are held.
@ -107,26 +106,19 @@ public class GossipSettings {
this.gossipInterval = gossipInterval; this.gossipInterval = gossipInterval;
} }
/**
* Set the cleanup interval. This is the time between the last heartbeat received from a member
* and when it will be marked as dead.
*
* @param cleanupInterval
* The cleanup interval in ms.
*/
public void setCleanupInterval(int cleanupInterval) {
this.cleanupInterval = cleanupInterval;
}
/** /**
* Get the gossip interval. * Get the gossip interval.
* *
* @return The gossip interval in ms. * @return The gossip interval in ms.
*/ */
public int getGossipInterval() { public int getGossipInterval() {
return gossipInterval; return gossipInterval;
} }
public void setGossipInterval(int gossipInterval) {
this.gossipInterval = gossipInterval;
}
/** /**
* Get the clean interval. * Get the clean interval.
* *
@ -136,6 +128,17 @@ public class GossipSettings {
return cleanupInterval; return cleanupInterval;
} }
/**
* Set the cleanup interval. This is the time between the last heartbeat received from a member
* and when it will be marked as dead.
*
* @param cleanupInterval
* The cleanup interval in ms.
*/
public void setCleanupInterval(int cleanupInterval) {
this.cleanupInterval = cleanupInterval;
}
public int getMinimumSamples() { public int getMinimumSamples() {
return minimumSamples; return minimumSamples;
} }
@ -160,10 +163,6 @@ public class GossipSettings {
this.convictThreshold = convictThreshold; this.convictThreshold = convictThreshold;
} }
public void setGossipInterval(int gossipInterval) {
this.gossipInterval = gossipInterval;
}
public String getDistribution() { public String getDistribution() {
return distribution; return distribution;
} }

View File

@ -25,35 +25,35 @@ import org.apache.gossip.accrual.FailureDetector;
/** /**
* This object represent a gossip member with the properties known locally. These objects are stored * This object represent a gossip member with the properties known locally. These objects are stored
* in the local list of gossip members. * in the local list of gossip members.
*
*/ */
public class LocalMember extends Member { public class LocalMember extends Member {
/** The failure detector for this member */ /** The failure detector for this member */
private transient FailureDetector detector; private transient FailureDetector detector;
/** /**
* * @param uri The uri of the member
* @param uri * @param id id of the node
* The uri of the member * @param heartbeat The current heartbeat
* @param id
* id of the node
* @param heartbeat
* The current heartbeat
*/ */
public LocalMember(String clusterName, URI uri, String id, public LocalMember(
long heartbeat, Map<String,String> properties, int windowSize, int minSamples, String distribution) { String clusterName,
super(clusterName, uri, id, heartbeat, properties ); URI uri,
String id,
long heartbeat,
Map<String, String> properties,
int windowSize,
int minSamples,
String distribution) {
super(clusterName, uri, id, heartbeat, properties);
detector = new FailureDetector(minSamples, windowSize, distribution); detector = new FailureDetector(minSamples, windowSize, distribution);
} }
protected LocalMember(){ protected LocalMember() {}
} public void recordHeartbeat(long now) {
public void recordHeartbeat(long now){
detector.recordHeartbeat(now); detector.recordHeartbeat(now);
} }
public Double detect(long now) { public Double detect(long now) {
return detector.computePhiMeasure(now); return detector.computePhiMeasure(now);
} }
@ -63,9 +63,18 @@ public class LocalMember extends Member {
Double d = null; Double d = null;
try { try {
d = detect(System.nanoTime()); d = detect(System.nanoTime());
} catch (RuntimeException ex) {} } catch (RuntimeException ex) {
return "LocalGossipMember [uri=" + uri + ", heartbeat=" + heartbeat + ", clusterName=" }
+ clusterName + ", id=" + id + ", currentdetect=" + d +" ]"; return "LocalGossipMember [uri="
+ uri
+ ", heartbeat="
+ heartbeat
+ ", clusterName="
+ clusterName
+ ", id="
+ id
+ ", currentdetect="
+ d
+ " ]";
} }
}
}

View File

@ -21,13 +21,9 @@ import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
/** /** An abstract class representing a gossip member. */
* An abstract class representing a gossip member.
*
*/
public abstract class Member implements Comparable<Member> { public abstract class Member implements Comparable<Member> {
protected URI uri; protected URI uri;
protected volatile long heartbeat; protected volatile long heartbeat;
@ -42,21 +38,18 @@ public abstract class Member implements Comparable<Member> {
protected String id; protected String id;
/* properties provided at startup time */ /* properties provided at startup time */
protected Map<String,String> properties; protected Map<String, String> properties;
/** /**
* Constructor. * Constructor.
* *
* @param clusterName * @param clusterName The name of the cluster
* The name of the cluster * @param uri A URI object containing IP/hostname and port
* @param uri * @param heartbeat The current heartbeat
* A URI object containing IP/hostname and port * @param id An id that may be replaced after contact
* @param heartbeat
* The current heartbeat
* @param id
* An id that may be replaced after contact
*/ */
public Member(String clusterName, URI uri, String id, long heartbeat, Map<String,String> properties) { public Member(
String clusterName, URI uri, String id, long heartbeat, Map<String, String> properties) {
this.clusterName = clusterName; this.clusterName = clusterName;
this.id = id; this.id = id;
this.heartbeat = heartbeat; this.heartbeat = heartbeat;
@ -64,20 +57,20 @@ public abstract class Member implements Comparable<Member> {
this.properties = properties; this.properties = properties;
} }
protected Member(){} protected Member() {}
/** /**
* Get the name of the cluster the member belongs to. * Get the name of the cluster the member belongs to.
* *
* @return The cluster name * @return The cluster name
*/ */
public String getClusterName() { public String getClusterName() {
return clusterName; return clusterName;
} }
/** /**
* @return The member address in the form IP/host:port Similar to the toString in * @return The member address in the form IP/host:port Similar to the toString in {@link
* {@link InetSocketAddress} * InetSocketAddress}
*/ */
public String computeAddress() { public String computeAddress() {
return uri.getHost() + ":" + uri.getPort(); return uri.getHost() + ":" + uri.getPort();
@ -85,7 +78,7 @@ public abstract class Member implements Comparable<Member> {
/** /**
* Get the heartbeat of this gossip member. * Get the heartbeat of this gossip member.
* *
* @return The current heartbeat. * @return The current heartbeat.
*/ */
public long getHeartbeat() { public long getHeartbeat() {
@ -94,9 +87,8 @@ public abstract class Member implements Comparable<Member> {
/** /**
* Set the heartbeat of this gossip member. * Set the heartbeat of this gossip member.
* *
* @param heartbeat * @param heartbeat The new heartbeat.
* The new heartbeat.
*/ */
public void setHeartbeat(long heartbeat) { public void setHeartbeat(long heartbeat) {
this.heartbeat = heartbeat; this.heartbeat = heartbeat;
@ -130,8 +122,10 @@ public abstract class Member implements Comparable<Member> {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
String address = computeAddress(); String address = computeAddress();
result = prime * result + ((address == null) ? 0 : address.hashCode()) + (clusterName == null ? 0 result =
: clusterName.hashCode()); prime * result
+ ((address == null) ? 0 : address.hashCode())
+ (clusterName == null ? 0 : clusterName.hashCode());
return result; return result;
} }
@ -157,7 +151,7 @@ public abstract class Member implements Comparable<Member> {
} }
// The object is the same of they both have the same address (hostname and port). // The object is the same of they both have the same address (hostname and port).
return computeAddress().equals(((LocalMember) obj).computeAddress()) return computeAddress().equals(((LocalMember) obj).computeAddress())
&& getClusterName().equals(((LocalMember) obj).getClusterName()); && getClusterName().equals(((LocalMember) obj).getClusterName());
} }
public int compareTo(Member other) { public int compareTo(Member other) {

View File

@ -24,24 +24,21 @@ import java.util.Map;
/** /**
* The object represents a gossip member with the properties as received from a remote gossip * The object represents a gossip member with the properties as received from a remote gossip
* member. * member.
*
*/ */
public class RemoteMember extends Member { public class RemoteMember extends Member {
/** /**
* Constructor. * Constructor.
* *
* @param uri * @param uri A URI object containing IP/hostname and port
* A URI object containing IP/hostname and port * @param heartbeat The current heartbeat
* @param heartbeat
* The current heartbeat
*/ */
public RemoteMember(String clusterName, URI uri, String id, long heartbeat, Map<String,String> properties) { public RemoteMember(
String clusterName, URI uri, String id, long heartbeat, Map<String, String> properties) {
super(clusterName, uri, id, heartbeat, properties); super(clusterName, uri, id, heartbeat, properties);
} }
public RemoteMember(String clusterName, URI uri, String id) { public RemoteMember(String clusterName, URI uri, String id) {
super(clusterName, uri, id, System.nanoTime(), new HashMap<String,String>()); super(clusterName, uri, id, System.nanoTime(), new HashMap<String, String>());
} }
} }

View File

@ -17,6 +17,8 @@
*/ */
package org.apache.gossip; package org.apache.gossip;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -28,36 +30,26 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.Logger;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
/** /**
* This object represents the settings used when starting the gossip service. * This object represents the settings used when starting the gossip service.
* *
*/ */
@Slf4j
public class StartupSettings { public class StartupSettings {
private static final Logger log = Logger.getLogger(StartupSettings.class);
/** The id to use fo the service */
private String id;
private URI uri;
private String cluster;
/** The gossip settings used at startup. */
private final GossipSettings gossipSettings;
/** The list with gossip members to start with. */
private final List<Member> gossipMembers;
public static final int DEFAULT_BULK_TRANSFER_SIZE = 100;
/** Default setting values */ /** Default setting values */
private static final boolean DEFAULT_BULK_TRANSFER = false; private static final boolean DEFAULT_BULK_TRANSFER = false;
public static final int DEFAULT_BULK_TRANSFER_SIZE = 100; /** The gossip settings used at startup. */
private final GossipSettings gossipSettings;
/** The list with gossip members to start with. */
private final List<Member> gossipMembers;
/** The id to use fo the service */
private String id;
private URI uri;
private String cluster;
/** /**
* Constructor. * Constructor.
@ -73,17 +65,9 @@ public class StartupSettings {
this(id, uri, new GossipSettings(), cluster); this(id, uri, new GossipSettings(), cluster);
} }
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
/** /**
* Constructor. * Constructor.
* *
* @param id * @param id
* The id to be used for this service * The id to be used for this service
* @param uri * @param uri
@ -97,64 +81,9 @@ public class StartupSettings {
gossipMembers = new ArrayList<>(); gossipMembers = new ArrayList<>();
} }
public void setCluster(String cluster) {
this.cluster = cluster;
}
public String getCluster() {
return cluster;
}
/**
* Set the id to be used for this service.
*
* @param id
* The id for this service.
*/
public void setId(String id) {
this.id = id;
}
/**
* Get the id for this service.
*
* @return the service's id.
*/
public String getId() {
return id;
}
/**
* Get the GossipSettings.
*
* @return The GossipSettings object.
*/
public GossipSettings getGossipSettings() {
return gossipSettings;
}
/**
* Add a gossip member to the list of members to start with.
*
* @param member
* The member to add.
*/
public void addGossipMember(Member member) {
gossipMembers.add(member);
}
/**
* Get the list with gossip members.
*
* @return The gossip members.
*/
public List<Member> getGossipMembers() {
return gossipMembers;
}
/** /**
* Parse the settings for the gossip service from a JSON file. * Parse the settings for the gossip service from a JSON file.
* *
* @param jsonFile * @param jsonFile
* The file object which refers to the JSON config file. * The file object which refers to the JSON config file.
* @return The StartupSettings object with the settings from the config file. * @return The StartupSettings object with the settings from the config file.
@ -162,9 +91,9 @@ public class StartupSettings {
* Thrown when the file cannot be found. * Thrown when the file cannot be found.
* @throws IOException * @throws IOException
* Thrown when reading the file gives problems. * Thrown when reading the file gives problems.
* @throws URISyntaxException * @throws URISyntaxException
*/ */
public static StartupSettings fromJSONFile(File jsonFile) throws public static StartupSettings fromJSONFile(File jsonFile) throws
FileNotFoundException, IOException, URISyntaxException { FileNotFoundException, IOException, URISyntaxException {
ObjectMapper om = new ObjectMapper(); ObjectMapper om = new ObjectMapper();
JsonNode root = om.readTree(jsonFile); JsonNode root = om.readTree(jsonFile);
@ -196,11 +125,11 @@ public class StartupSettings {
if (cluster == null){ if (cluster == null){
throw new IllegalArgumentException("cluster was null. It is required"); throw new IllegalArgumentException("cluster was null. It is required");
} }
String transportClass = jsonObject.has("transport_manager_class") ? String transportClass = jsonObject.has("transport_manager_class") ?
jsonObject.get("transport_manager_class").textValue() : jsonObject.get("transport_manager_class").textValue() :
null; null;
String protocolClass = jsonObject.has("protocol_manager_class") ? String protocolClass = jsonObject.has("protocol_manager_class") ?
jsonObject.get("protocol_manager_class").textValue() : jsonObject.get("protocol_manager_class").textValue() :
null; null;
URI uri2 = new URI(uri); URI uri2 = new URI(uri);
GossipSettings gossipSettings = new GossipSettings(gossipInterval, cleanupInterval, windowSize, GossipSettings gossipSettings = new GossipSettings(gossipInterval, cleanupInterval, windowSize,
@ -215,17 +144,79 @@ public class StartupSettings {
StartupSettings settings = new StartupSettings(id, uri2, gossipSettings, cluster); StartupSettings settings = new StartupSettings(id, uri2, gossipSettings, cluster);
String configMembersDetails = "Config-members ["; String configMembersDetails = "Config-members [";
JsonNode membersJSON = jsonObject.get("members"); JsonNode membersJSON = jsonObject.get("members");
Iterator<JsonNode> it = membersJSON.iterator(); for (JsonNode child : membersJSON) {
while (it.hasNext()){ URI uri3 = new URI(child.get("uri").textValue());
JsonNode child = it.next(); RemoteMember member = new RemoteMember(child.get("cluster").asText(),
URI uri3 = new URI(child.get("uri").textValue()); uri3, "", 0, new HashMap<String, String>()
RemoteMember member = new RemoteMember(child.get("cluster").asText(), );
uri3, "", 0, new HashMap<String,String>()); settings.addGossipMember(member);
settings.addGossipMember(member); configMembersDetails += member.computeAddress();
configMembersDetails += member.computeAddress(); configMembersDetails += ", ";
configMembersDetails += ", "; }
}
log.info(configMembersDetails + "]"); log.info(configMembersDetails + "]");
return settings; return settings;
} }
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
public String getCluster() {
return cluster;
}
public void setCluster(String cluster) {
this.cluster = cluster;
}
/**
* Get the id for this service.
*
* @return the service's id.
*/
public String getId() {
return id;
}
/**
* Set the id to be used for this service.
*
* @param id
* The id for this service.
*/
public void setId(String id) {
this.id = id;
}
/**
* Get the GossipSettings.
*
* @return The GossipSettings object.
*/
public GossipSettings getGossipSettings() {
return gossipSettings;
}
/**
* Add a gossip member to the list of members to start with.
*
* @param member
* The member to add.
*/
public void addGossipMember(Member member) {
gossipMembers.add(member);
}
/**
* Get the list with gossip members.
*
* @return The gossip members.
*/
public List<Member> getGossipMembers() {
return gossipMembers;
}
} }

View File

@ -17,19 +17,19 @@
*/ */
package org.apache.gossip.accrual; package org.apache.gossip.accrual;
import org.apache.commons.math.MathException; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math.distribution.ExponentialDistributionImpl; import org.apache.commons.math3.distribution.ExponentialDistribution;
import org.apache.commons.math.distribution.NormalDistributionImpl; import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math3.exception.MathArithmeticException;
import org.apache.log4j.Logger; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
@Slf4j
public class FailureDetector { public class FailureDetector {
public static final Logger LOGGER = Logger.getLogger(FailureDetector.class);
private final DescriptiveStatistics descriptiveStatistics; private final DescriptiveStatistics descriptiveStatistics;
private final long minimumSamples; private final long minimumSamples;
private volatile long latestHeartbeatMs = -1;
private final String distribution; private final String distribution;
private volatile long latestHeartbeatMs = -1;
public FailureDetector(long minimumSamples, int windowSize, String distribution) { public FailureDetector(long minimumSamples, int windowSize, String distribution) {
descriptiveStatistics = new DescriptiveStatistics(windowSize); descriptiveStatistics = new DescriptiveStatistics(windowSize);
@ -62,18 +62,18 @@ public class FailureDetector {
double probability; double probability;
if (distribution.equals("normal")) { if (distribution.equals("normal")) {
double standardDeviation = descriptiveStatistics.getStandardDeviation(); double standardDeviation = descriptiveStatistics.getStandardDeviation();
standardDeviation = standardDeviation < 0.1 ? 0.1 : standardDeviation; standardDeviation = Math.max(standardDeviation, 0.1);
probability = new NormalDistributionImpl(descriptiveStatistics.getMean(), standardDeviation).cumulativeProbability(delta); probability = new NormalDistribution(descriptiveStatistics.getMean(), standardDeviation).cumulativeProbability(delta);
} else { } else {
probability = new ExponentialDistributionImpl(descriptiveStatistics.getMean()).cumulativeProbability(delta); probability = new ExponentialDistribution(descriptiveStatistics.getMean()).cumulativeProbability(delta);
} }
final double eps = 1e-12; final double eps = 1e-12;
if (1 - probability < eps) { if (1 - probability < eps) {
probability = 1.0; probability = 1.0;
} }
return -1.0d * Math.log10(1.0d - probability); return -1.0d * Math.log10(1.0d - probability);
} catch (MathException | IllegalArgumentException e) { } catch (MathArithmeticException | IllegalArgumentException e) {
LOGGER.debug(e); log.error("Error!", e);
return null; return null;
} }
} }

View File

@ -16,24 +16,24 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
/** /**
* * Immutable type
* Immutable type
* *
* @param <SetType> * @param <SetType>
* @param <MergeReturnType> * @param <MergeReturnType>
*/ */
public interface Crdt<SetType, MergeReturnType extends Crdt<SetType, MergeReturnType>> { public interface Crdt<SetType, MergeReturnType extends Crdt<SetType, MergeReturnType>> {
MergeReturnType merge(MergeReturnType other); MergeReturnType merge(MergeReturnType other);
SetType value(); SetType value();
/** /**
* Called to self optimize. Some CRDTs may use some mechanism to clean up be * Called to self optimize. Some CRDTs may use some mechanism to clean up be removing obsolete
* removing obsolete data outside the scope of merging. IE this could clean up * data outside the scope of merging. IE this could clean up temporal values, old copies etc.
* temporal values, old copies etc. *
* @return the Crdt structure optimized * @return the Crdt structure optimized
*/ */
MergeReturnType optimize(); MergeReturnType optimize();
} }

View File

@ -19,10 +19,14 @@ package org.apache.gossip.crdt;
import java.util.Set; import java.util.Set;
// Interface extends CrdtSet interface with add and remove operation that are guaranteed to be immutable. // Interface extends CrdtSet interface with add and remove operation that are guaranteed to be
// If your implementation provide immutable add/remove operations you can extend AbstractCRDTStringSetTest to check it in the most ways. // immutable.
// If your implementation provide immutable add/remove operations you can extend
// AbstractCRDTStringSetTest to check it in the most ways.
public interface CrdtAddRemoveSet<T, SetType extends Set<T>, R extends CrdtAddRemoveSet<T, SetType, R>> extends CrdtSet<T, SetType, R> { public interface CrdtAddRemoveSet<
T, SetType extends Set<T>, R extends CrdtAddRemoveSet<T, SetType, R>>
extends CrdtSet<T, SetType, R> {
R add(T element); R add(T element);
R remove(T element); R remove(T element);

View File

@ -20,35 +20,35 @@ package org.apache.gossip.crdt;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class CrdtBiFunctionMerge implements BiFunction<Crdt,Crdt,Crdt> { public class CrdtBiFunctionMerge implements BiFunction<Crdt, Crdt, Crdt> {
@SuppressWarnings("unchecked")
public static Crdt applyStatic(Crdt t, Crdt u) {
if (t == null && u == null) {
return null;
} else if (t == null) {
return u;
} else if (u == null) {
return t;
}
if (!u.getClass().equals(t.getClass())) {
throw new IllegalArgumentException("Can not merge " + t.getClass() + " " + u.getClass());
}
return t.merge(u);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Crdt apply(Crdt t, Crdt u) { public Crdt apply(Crdt t, Crdt u) {
if (t == null && u == null){ if (t == null && u == null) {
return null; return null;
} else if (t == null){ } else if (t == null) {
return u; return u;
} else if (u == null){ } else if (u == null) {
return t; return t;
} }
if (! u.getClass().equals(t.getClass())){ if (!u.getClass().equals(t.getClass())) {
throw new IllegalArgumentException( "Can not merge " + t.getClass() + " "+ u.getClass()); throw new IllegalArgumentException("Can not merge " + t.getClass() + " " + u.getClass());
}
return t.merge(u);
}
@SuppressWarnings("unchecked")
public static Crdt applyStatic(Crdt t, Crdt u){
if (t == null && u == null){
return null;
} else if (t == null){
return u;
} else if (u == null){
return t;
}
if (! u.getClass().equals(t.getClass())){
throw new IllegalArgumentException( "Can not merge " + t.getClass() + " "+ u.getClass());
} }
return t.merge(u); return t.merge(u);
} }

View File

@ -18,7 +18,4 @@
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
public interface CrdtCounter<ValueType extends Number, R extends CrdtCounter<ValueType, R>> public interface CrdtCounter<ValueType extends Number, R extends CrdtCounter<ValueType, R>>
extends Crdt<ValueType, R> { extends Crdt<ValueType, R> {}
}

View File

@ -23,6 +23,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.module.SimpleModule;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.lock.vote.MajorityVote; import org.apache.gossip.lock.vote.MajorityVote;
import org.apache.gossip.lock.vote.Vote; import org.apache.gossip.lock.vote.Vote;
@ -31,11 +35,6 @@ import org.apache.gossip.replication.BlackListReplicable;
import org.apache.gossip.replication.Replicable; import org.apache.gossip.replication.Replicable;
import org.apache.gossip.replication.WhiteListReplicable; import org.apache.gossip.replication.WhiteListReplicable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
abstract class OrSetMixin<E> { abstract class OrSetMixin<E> {
@JsonCreator @JsonCreator
OrSetMixin(@JsonProperty("elements") Map<E, Set<UUID>> w, @JsonProperty("tombstones") Map<E, Set<UUID>> h) { } OrSetMixin(@JsonProperty("elements") Map<E, Set<UUID>> w, @JsonProperty("tombstones") Map<E, Set<UUID>> h) { }

View File

@ -19,8 +19,6 @@ package org.apache.gossip.crdt;
import java.util.Set; import java.util.Set;
public interface CrdtSet<ElementType, SetType extends Set<ElementType>, R extends CrdtSet<ElementType, SetType, R>> public interface CrdtSet<
extends Crdt<SetType, R> { ElementType, SetType extends Set<ElementType>, R extends CrdtSet<ElementType, SetType, R>>
extends Crdt<SetType, R> {}
}

View File

@ -18,10 +18,9 @@
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
import org.apache.gossip.manager.GossipManager;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.gossip.manager.GossipManager;
public class GrowOnlyCounter implements CrdtCounter<Long, GrowOnlyCounter> { public class GrowOnlyCounter implements CrdtCounter<Long, GrowOnlyCounter> {

View File

@ -24,31 +24,30 @@ import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
public class GrowOnlySet<ElementType> implements CrdtSet<ElementType, Set<ElementType>, GrowOnlySet<ElementType>>{ public class GrowOnlySet<ElementType>
implements CrdtSet<ElementType, Set<ElementType>, GrowOnlySet<ElementType>> {
private final Set<ElementType> hidden = new LinkedHashSet<>(); private final Set<ElementType> hidden = new LinkedHashSet<>();
@SuppressWarnings("unused") @SuppressWarnings("unused")
/* /*
* Used by SerDe * Used by SerDe
*/ */
private GrowOnlySet(){ private GrowOnlySet() {}
} public GrowOnlySet(Set<ElementType> c) {
public GrowOnlySet(Set<ElementType> c){
hidden.addAll(c); hidden.addAll(c);
} }
public GrowOnlySet(Collection<ElementType> c){ public GrowOnlySet(Collection<ElementType> c) {
hidden.addAll(c); hidden.addAll(c);
} }
public GrowOnlySet(GrowOnlySet<ElementType> first, GrowOnlySet<ElementType> second){ public GrowOnlySet(GrowOnlySet<ElementType> first, GrowOnlySet<ElementType> second) {
hidden.addAll(first.value()); hidden.addAll(first.value());
hidden.addAll(second.value()); hidden.addAll(second.value());
} }
@Override @Override
public GrowOnlySet<ElementType> merge(GrowOnlySet<ElementType> other) { public GrowOnlySet<ElementType> merge(GrowOnlySet<ElementType> other) {
return new GrowOnlySet<>(this, other); return new GrowOnlySet<>(this, other);
@ -60,7 +59,7 @@ public class GrowOnlySet<ElementType> implements CrdtSet<ElementType, Set<Elemen
copy.addAll(hidden); copy.addAll(hidden);
return Collections.unmodifiableSet(copy); return Collections.unmodifiableSet(copy);
} }
@Override @Override
public GrowOnlySet<ElementType> optimize() { public GrowOnlySet<ElementType> optimize() {
return new GrowOnlySet<>(hidden); return new GrowOnlySet<>(hidden);
@ -135,23 +134,18 @@ public class GrowOnlySet<ElementType> implements CrdtSet<ElementType, Set<Elemen
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj) return true;
return true; if (obj == null) return false;
if (obj == null) if (getClass() != obj.getClass()) return false;
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
GrowOnlySet other = (GrowOnlySet) obj; GrowOnlySet other = (GrowOnlySet) obj;
if (hidden == null) { if (hidden == null) {
if (other.hidden != null) if (other.hidden != null) return false;
return false; } else if (!hidden.equals(other.hidden)) return false;
} else if (!hidden.equals(other.hidden))
return false;
return true; return true;
} }
Set<ElementType> getElements(){ Set<ElementType> getElements() {
return hidden; return hidden;
} }
} }

View File

@ -17,9 +17,6 @@
*/ */
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
import org.apache.gossip.manager.Clock;
import org.apache.gossip.manager.SystemClock;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -28,6 +25,8 @@ import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.gossip.manager.Clock;
import org.apache.gossip.manager.SystemClock;
/* /*
Last write wins CrdtSet Last write wins CrdtSet
@ -49,6 +48,82 @@ public class LwwSet<ElementType> implements CrdtAddRemoveSet<ElementType, Set<El
private final Map<ElementType, Timestamps> struct; private final Map<ElementType, Timestamps> struct;
public LwwSet(){
struct = new HashMap<>();
}
@SafeVarargs
public LwwSet(ElementType... elements){
this(new HashSet<>(Arrays.asList(elements)));
}
public LwwSet(Set<ElementType> set){
struct = new HashMap<>();
for (ElementType e : set){
struct.put(e, new Timestamps().updateAdd());
}
}
public LwwSet(LwwSet<ElementType> first, LwwSet<ElementType> second){
Function<ElementType, Timestamps> timestampsFor = p -> {
Timestamps firstTs = first.struct.get(p);
Timestamps secondTs = second.struct.get(p);
if (firstTs == null){
return secondTs;
}
return firstTs.merge(secondTs);
};
struct = Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream())
.distinct().collect(Collectors.toMap(p -> p, timestampsFor));
}
// for serialization
LwwSet(Map<ElementType, Timestamps> struct){
this.struct = struct;
}
public LwwSet<ElementType> add(ElementType e){
return this.merge(new LwwSet<>(e));
}
Map<ElementType, Timestamps> getStruct(){
return struct;
}
public LwwSet<ElementType> remove(ElementType e){
Timestamps eTimestamps = struct.get(e);
if (eTimestamps == null || !eTimestamps.isPresent()){
return this;
}
Map<ElementType, Timestamps> changeMap = new HashMap<>();
changeMap.put(e, eTimestamps.updateRemove());
return this.merge(new LwwSet<>(changeMap));
}
@Override
public LwwSet<ElementType> merge(LwwSet<ElementType> other){
return new LwwSet<>(this, other);
}
@Override
public Set<ElementType> value(){
return struct.entrySet().stream()
.filter(entry -> entry.getValue().isPresent())
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
@Override
public LwwSet<ElementType> optimize(){
return this;
}
@Override
public boolean equals(Object obj){
return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((LwwSet) obj).value()));
}
static class Timestamps { static class Timestamps {
private final long latestAdd; private final long latestAdd;
private final long latestRemove; private final long latestRemove;
@ -91,81 +166,4 @@ public class LwwSet<ElementType> implements CrdtAddRemoveSet<ElementType, Set<El
return new Timestamps(Math.max(latestAdd, other.latestAdd), Math.max(latestRemove, other.latestRemove)); return new Timestamps(Math.max(latestAdd, other.latestAdd), Math.max(latestRemove, other.latestRemove));
} }
} }
public LwwSet(){
struct = new HashMap<>();
}
@SafeVarargs
public LwwSet(ElementType... elements){
this(new HashSet<>(Arrays.asList(elements)));
}
public LwwSet(Set<ElementType> set){
struct = new HashMap<>();
for (ElementType e : set){
struct.put(e, new Timestamps().updateAdd());
}
}
public LwwSet(LwwSet<ElementType> first, LwwSet<ElementType> second){
Function<ElementType, Timestamps> timestampsFor = p -> {
Timestamps firstTs = first.struct.get(p);
Timestamps secondTs = second.struct.get(p);
if (firstTs == null){
return secondTs;
}
return firstTs.merge(secondTs);
};
struct = Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream())
.distinct().collect(Collectors.toMap(p -> p, timestampsFor));
}
public LwwSet<ElementType> add(ElementType e){
return this.merge(new LwwSet<>(e));
}
// for serialization
LwwSet(Map<ElementType, Timestamps> struct){
this.struct = struct;
}
Map<ElementType, Timestamps> getStruct(){
return struct;
}
public LwwSet<ElementType> remove(ElementType e){
Timestamps eTimestamps = struct.get(e);
if (eTimestamps == null || !eTimestamps.isPresent()){
return this;
}
Map<ElementType, Timestamps> changeMap = new HashMap<>();
changeMap.put(e, eTimestamps.updateRemove());
return this.merge(new LwwSet<>(changeMap));
}
@Override
public LwwSet<ElementType> merge(LwwSet<ElementType> other){
return new LwwSet<>(this, other);
}
@Override
public Set<ElementType> value(){
return struct.entrySet().stream()
.filter(entry -> entry.getValue().isPresent())
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
@Override
public LwwSet<ElementType> optimize(){
return this;
}
@Override
public boolean equals(Object obj){
return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((LwwSet) obj).value()));
}
} }

View File

@ -37,68 +37,72 @@ import java.util.stream.Stream;
DataTest - integration test with 2 nodes, MaxChangeSet was serialized/deserialized, sent between nodes, merged DataTest - integration test with 2 nodes, MaxChangeSet was serialized/deserialized, sent between nodes, merged
*/ */
public class MaxChangeSet<ElementType> implements CrdtAddRemoveSet<ElementType, Set<ElementType>, MaxChangeSet<ElementType>> { public class MaxChangeSet<ElementType>
implements CrdtAddRemoveSet<ElementType, Set<ElementType>, MaxChangeSet<ElementType>> {
private final Map<ElementType, Integer> struct; private final Map<ElementType, Integer> struct;
public MaxChangeSet(){ public MaxChangeSet() {
struct = new HashMap<>(); struct = new HashMap<>();
} }
@SafeVarargs @SafeVarargs
public MaxChangeSet(ElementType... elements){ public MaxChangeSet(ElementType... elements) {
this(new HashSet<>(Arrays.asList(elements))); this(new HashSet<>(Arrays.asList(elements)));
} }
public MaxChangeSet(Set<ElementType> set){ public MaxChangeSet(Set<ElementType> set) {
struct = new HashMap<>(); struct = new HashMap<>();
for (ElementType e : set){ for (ElementType e : set) {
struct.put(e, 1); struct.put(e, 1);
} }
} }
public MaxChangeSet(MaxChangeSet<ElementType> first, MaxChangeSet<ElementType> second){ public MaxChangeSet(MaxChangeSet<ElementType> first, MaxChangeSet<ElementType> second) {
Function<ElementType, Integer> valueFor = element -> Function<ElementType, Integer> valueFor =
Math.max(first.struct.getOrDefault(element, 0), second.struct.getOrDefault(element, 0)); element ->
struct = Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream()) Math.max(first.struct.getOrDefault(element, 0), second.struct.getOrDefault(element, 0));
.distinct().collect(Collectors.toMap(p -> p, valueFor)); struct =
Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream())
.distinct()
.collect(Collectors.toMap(p -> p, valueFor));
} }
// for serialization // for serialization
MaxChangeSet(Map<ElementType, Integer> struct){ MaxChangeSet(Map<ElementType, Integer> struct) {
this.struct = struct; this.struct = struct;
} }
Map<ElementType, Integer> getStruct(){ Map<ElementType, Integer> getStruct() {
return struct; return struct;
} }
private MaxChangeSet<ElementType> increment(ElementType e){ private MaxChangeSet<ElementType> increment(ElementType e) {
Map<ElementType, Integer> changeMap = new HashMap<>(); Map<ElementType, Integer> changeMap = new HashMap<>();
changeMap.put(e, struct.getOrDefault(e, 0) + 1); changeMap.put(e, struct.getOrDefault(e, 0) + 1);
return this.merge(new MaxChangeSet<>(changeMap)); return this.merge(new MaxChangeSet<>(changeMap));
} }
public MaxChangeSet<ElementType> add(ElementType e){ public MaxChangeSet<ElementType> add(ElementType e) {
if (struct.getOrDefault(e, 0) % 2 == 1){ if (struct.getOrDefault(e, 0) % 2 == 1) {
return this; return this;
} }
return increment(e); return increment(e);
} }
public MaxChangeSet<ElementType> remove(ElementType e){ public MaxChangeSet<ElementType> remove(ElementType e) {
if (struct.getOrDefault(e, 0) % 2 == 0){ if (struct.getOrDefault(e, 0) % 2 == 0) {
return this; return this;
} }
return increment(e); return increment(e);
} }
@Override @Override
public MaxChangeSet<ElementType> merge(MaxChangeSet<ElementType> other){ public MaxChangeSet<ElementType> merge(MaxChangeSet<ElementType> other) {
return new MaxChangeSet<>(this, other); return new MaxChangeSet<>(this, other);
} }
@Override @Override
public Set<ElementType> value(){ public Set<ElementType> value() {
return struct.entrySet().stream() return struct.entrySet().stream()
.filter(entry -> (entry.getValue() % 2 == 1)) .filter(entry -> (entry.getValue() % 2 == 1))
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
@ -106,12 +110,15 @@ public class MaxChangeSet<ElementType> implements CrdtAddRemoveSet<ElementType,
} }
@Override @Override
public MaxChangeSet<ElementType> optimize(){ public MaxChangeSet<ElementType> optimize() {
return this; return this;
} }
@Override @Override
public boolean equals(Object obj){ public boolean equals(Object obj) {
return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((MaxChangeSet) obj).value())); return this == obj
|| (obj != null
&& getClass() == obj.getClass()
&& value().equals(((MaxChangeSet) obj).value()));
} }
} }

View File

@ -20,7 +20,6 @@ package org.apache.gossip.crdt;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import org.apache.gossip.crdt.OrSet.Builder.Operation; import org.apache.gossip.crdt.OrSet.Builder.Operation;
/* /*
@ -83,6 +82,21 @@ public class OrSet<E> implements CrdtAddRemoveSet<E, Set<E>, OrSet<E>> {
val = computeValue(); val = computeValue();
} }
public OrSet(OrSet<E> left, OrSet<E> right){
BiConsumer<Map<E, Set<UUID>>, Map<E, Set<UUID>>> internalMerge = (items, other) -> {
for (Entry<E, Set<UUID>> l : other.entrySet()){
internalSetMerge(items, l.getKey(), l.getValue());
}
};
internalMerge.accept(elements, left.elements);
internalMerge.accept(elements, right.elements);
internalMerge.accept(tombstones, left.tombstones);
internalMerge.accept(tombstones, right.tombstones);
val = computeValue();
}
static Set<UUID> mergeSets(Set<UUID> a, Set<UUID> b) { static Set<UUID> mergeSets(Set<UUID> a, Set<UUID> b) {
if ((a == null || a.isEmpty()) && (b == null || b.isEmpty())) { if ((a == null || a.isEmpty()) && (b == null || b.isEmpty())) {
return null; return null;
@ -99,21 +113,6 @@ public class OrSet<E> implements CrdtAddRemoveSet<E, Set<E>, OrSet<E>> {
map.merge(key, value, OrSet::mergeSets); map.merge(key, value, OrSet::mergeSets);
} }
public OrSet(OrSet<E> left, OrSet<E> right){
BiConsumer<Map<E, Set<UUID>>, Map<E, Set<UUID>>> internalMerge = (items, other) -> {
for (Entry<E, Set<UUID>> l : other.entrySet()){
internalSetMerge(items, l.getKey(), l.getValue());
}
};
internalMerge.accept(elements, left.elements);
internalMerge.accept(elements, right.elements);
internalMerge.accept(tombstones, left.tombstones);
internalMerge.accept(tombstones, right.tombstones);
val = computeValue();
}
public OrSet<E> add(E e) { public OrSet<E> add(E e) {
return this.merge(new OrSet<>(e)); return this.merge(new OrSet<>(e));
} }
@ -166,55 +165,18 @@ public class OrSet<E> implements CrdtAddRemoveSet<E, Set<E>, OrSet<E>> {
return this; return this;
} }
public static class Builder<E> {
public static enum Operation {
ADD, REMOVE
};
private class OrSetElement<EL> {
EL element;
Operation operation;
private OrSetElement(EL element, Operation operation) {
this.element = element;
this.operation = operation;
}
}
private List<OrSetElement<E>> elements = new ArrayList<>();
public Builder<E> add(E element) {
elements.add(new OrSetElement<E>(element, Operation.ADD));
return this;
}
public Builder<E> remove(E element) {
elements.add(new OrSetElement<E>(element, Operation.REMOVE));
return this;
}
public Builder<E> mutate(E element, Operation operation) {
elements.add(new OrSetElement<E>(element, operation));
return this;
}
}
public int size() { public int size() {
return value().size(); return value().size();
} }
public boolean isEmpty() { public boolean isEmpty() {
return value().size() == 0; return value().size() == 0;
} }
public boolean contains(Object o) { public boolean contains(Object o) {
return value().contains(o); return value().contains(o);
} }
public Iterator<E> iterator() { public Iterator<E> iterator() {
Iterator<E> managed = value().iterator(); Iterator<E> managed = value().iterator();
return new Iterator<E>() { return new Iterator<E>() {
@ -233,7 +195,7 @@ public class OrSet<E> implements CrdtAddRemoveSet<E, Set<E>, OrSet<E>> {
public E next() { public E next() {
return managed.next(); return managed.next();
} }
}; };
} }
@ -304,4 +266,37 @@ public class OrSet<E> implements CrdtAddRemoveSet<E, Set<E>, OrSet<E>> {
return tombstones; return tombstones;
} }
public static class Builder<E> {
private List<OrSetElement<E>> elements = new ArrayList<>();;
public Builder<E> add(E element) {
elements.add(new OrSetElement<E>(element, Operation.ADD));
return this;
}
public Builder<E> remove(E element) {
elements.add(new OrSetElement<E>(element, Operation.REMOVE));
return this;
}
public Builder<E> mutate(E element, Operation operation) {
elements.add(new OrSetElement<E>(element, operation));
return this;
}
public static enum Operation {
ADD, REMOVE
}
private class OrSetElement<EL> {
EL element;
Operation operation;
private OrSetElement(EL element, Operation operation) {
this.element = element;
this.operation = operation;
}
}
}
} }

View File

@ -18,7 +18,6 @@
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
import java.util.Map; import java.util.Map;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
public class PNCounter implements CrdtCounter<Long, PNCounter> { public class PNCounter implements CrdtCounter<Long, PNCounter> {

View File

@ -36,57 +36,58 @@ import java.util.stream.Stream;
DataTest - integration test with 2 nodes, TwoPhaseSet was serialized/deserialized, sent between nodes, merged DataTest - integration test with 2 nodes, TwoPhaseSet was serialized/deserialized, sent between nodes, merged
*/ */
public class TwoPhaseSet<ElementType> implements CrdtAddRemoveSet<ElementType, Set<ElementType>, TwoPhaseSet<ElementType>> { public class TwoPhaseSet<ElementType>
implements CrdtAddRemoveSet<ElementType, Set<ElementType>, TwoPhaseSet<ElementType>> {
private final Set<ElementType> added; private final Set<ElementType> added;
private final Set<ElementType> removed; private final Set<ElementType> removed;
public TwoPhaseSet(){ public TwoPhaseSet() {
added = new HashSet<>(); added = new HashSet<>();
removed = new HashSet<>(); removed = new HashSet<>();
} }
@SafeVarargs @SafeVarargs
public TwoPhaseSet(ElementType... elements){ public TwoPhaseSet(ElementType... elements) {
this(new HashSet<>(Arrays.asList(elements))); this(new HashSet<>(Arrays.asList(elements)));
} }
public TwoPhaseSet(Set<ElementType> set){ public TwoPhaseSet(Set<ElementType> set) {
this(); this();
for (ElementType e : set){ for (ElementType e : set) {
added.add(e); added.add(e);
} }
} }
public TwoPhaseSet(TwoPhaseSet<ElementType> first, TwoPhaseSet<ElementType> second){ public TwoPhaseSet(TwoPhaseSet<ElementType> first, TwoPhaseSet<ElementType> second) {
BiFunction<Set<ElementType>, Set<ElementType>, Set<ElementType>> mergeSets = (f, s) -> BiFunction<Set<ElementType>, Set<ElementType>, Set<ElementType>> mergeSets =
Stream.concat(f.stream(), s.stream()).collect(Collectors.toSet()); (f, s) -> Stream.concat(f.stream(), s.stream()).collect(Collectors.toSet());
added = mergeSets.apply(first.added, second.added); added = mergeSets.apply(first.added, second.added);
removed = mergeSets.apply(first.removed, second.removed); removed = mergeSets.apply(first.removed, second.removed);
} }
TwoPhaseSet(Set<ElementType> added, Set<ElementType> removed){ TwoPhaseSet(Set<ElementType> added, Set<ElementType> removed) {
this.added = added; this.added = added;
this.removed = removed; this.removed = removed;
} }
Set<ElementType> getAdded(){ Set<ElementType> getAdded() {
return added; return added;
} }
Set<ElementType> getRemoved(){ Set<ElementType> getRemoved() {
return removed; return removed;
} }
public TwoPhaseSet<ElementType> add(ElementType e){ public TwoPhaseSet<ElementType> add(ElementType e) {
if (removed.contains(e) || added.contains(e)){ if (removed.contains(e) || added.contains(e)) {
return this; return this;
} }
return this.merge(new TwoPhaseSet<>(e)); return this.merge(new TwoPhaseSet<>(e));
} }
public TwoPhaseSet<ElementType> remove(ElementType e){ public TwoPhaseSet<ElementType> remove(ElementType e) {
if (removed.contains(e) || !added.contains(e)){ if (removed.contains(e) || !added.contains(e)) {
return this; return this;
} }
Set<ElementType> eSet = new HashSet<>(Collections.singletonList(e)); Set<ElementType> eSet = new HashSet<>(Collections.singletonList(e));
@ -94,22 +95,25 @@ public class TwoPhaseSet<ElementType> implements CrdtAddRemoveSet<ElementType, S
} }
@Override @Override
public TwoPhaseSet<ElementType> merge(TwoPhaseSet<ElementType> other){ public TwoPhaseSet<ElementType> merge(TwoPhaseSet<ElementType> other) {
return new TwoPhaseSet<>(this, other); return new TwoPhaseSet<>(this, other);
} }
@Override @Override
public Set<ElementType> value(){ public Set<ElementType> value() {
return added.stream().filter(e -> !removed.contains(e)).collect(Collectors.toSet()); return added.stream().filter(e -> !removed.contains(e)).collect(Collectors.toSet());
} }
@Override @Override
public TwoPhaseSet<ElementType> optimize(){ public TwoPhaseSet<ElementType> optimize() {
return new TwoPhaseSet<>(value(), removed); return new TwoPhaseSet<>(value(), removed);
} }
@Override @Override
public boolean equals(Object obj){ public boolean equals(Object obj) {
return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((TwoPhaseSet) obj).value())); return this == obj
|| (obj != null
&& getClass() == obj.getClass()
&& value().equals(((TwoPhaseSet) obj).value()));
} }
} }

View File

@ -18,7 +18,9 @@
package org.apache.gossip.event; package org.apache.gossip.event;
public enum GossipState { public enum GossipState {
UP("up"), DOWN("down"); UP("up"),
DOWN("down");
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String state; private final String state;

View File

@ -18,17 +18,17 @@
package org.apache.gossip.event.data; package org.apache.gossip.event.data;
public class DataEventConstants { public class DataEventConstants {
// MetricRegistry // MetricRegistry
public static final String PER_NODE_DATA_SUBSCRIBERS_SIZE public static final String PER_NODE_DATA_SUBSCRIBERS_SIZE =
= "gossip.event.data.pernode.subscribers.size"; "gossip.event.data.pernode.subscribers.size";
public static final String PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE public static final String PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE =
= "gossip.event.data.pernode.subscribers.queue.size"; "gossip.event.data.pernode.subscribers.queue.size";
public static final String SHARED_DATA_SUBSCRIBERS_SIZE public static final String SHARED_DATA_SUBSCRIBERS_SIZE =
= "gossip.event.data.shared.subscribers.size"; "gossip.event.data.shared.subscribers.size";
public static final String SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE public static final String SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE =
= "gossip.event.data.shared.subscribers.queue.size"; "gossip.event.data.shared.subscribers.queue.size";
// Thread pool // Thread pool
public static final int PER_NODE_DATA_QUEUE_SIZE = 64; public static final int PER_NODE_DATA_QUEUE_SIZE = 64;
public static final int PER_NODE_DATA_CORE_POOL_SIZE = 1; public static final int PER_NODE_DATA_CORE_POOL_SIZE = 1;
@ -38,5 +38,4 @@ public class DataEventConstants {
public static final int SHARED_DATA_CORE_POOL_SIZE = 1; public static final int SHARED_DATA_CORE_POOL_SIZE = 1;
public static final int SHARED_DATA_MAX_POOL_SIZE = 30; public static final int SHARED_DATA_MAX_POOL_SIZE = 30;
public static final int SHARED_DATA_KEEP_ALIVE_TIME_SECONDS = 1; public static final int SHARED_DATA_KEEP_ALIVE_TIME_SECONDS = 1;
} }

View File

@ -29,74 +29,86 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class DataEventManager { public class DataEventManager {
private final List<UpdateNodeDataEventHandler> perNodeDataHandlers; private final List<UpdateNodeDataEventHandler> perNodeDataHandlers;
private final BlockingQueue<Runnable> perNodeDataHandlerQueue; private final BlockingQueue<Runnable> perNodeDataHandlerQueue;
private final ExecutorService perNodeDataEventExecutor; private final ExecutorService perNodeDataEventExecutor;
private final List<UpdateSharedDataEventHandler> sharedDataHandlers; private final List<UpdateSharedDataEventHandler> sharedDataHandlers;
private final BlockingQueue<Runnable> sharedDataHandlerQueue; private final BlockingQueue<Runnable> sharedDataHandlerQueue;
private final ExecutorService sharedDataEventExecutor; private final ExecutorService sharedDataEventExecutor;
public DataEventManager(MetricRegistry metrics) { public DataEventManager(MetricRegistry metrics) {
perNodeDataHandlers = new CopyOnWriteArrayList<>(); perNodeDataHandlers = new CopyOnWriteArrayList<>();
perNodeDataHandlerQueue = new ArrayBlockingQueue<>(DataEventConstants.PER_NODE_DATA_QUEUE_SIZE); perNodeDataHandlerQueue = new ArrayBlockingQueue<>(DataEventConstants.PER_NODE_DATA_QUEUE_SIZE);
perNodeDataEventExecutor = new ThreadPoolExecutor( perNodeDataEventExecutor =
new ThreadPoolExecutor(
DataEventConstants.PER_NODE_DATA_CORE_POOL_SIZE, DataEventConstants.PER_NODE_DATA_CORE_POOL_SIZE,
DataEventConstants.PER_NODE_DATA_MAX_POOL_SIZE, DataEventConstants.PER_NODE_DATA_MAX_POOL_SIZE,
DataEventConstants.PER_NODE_DATA_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS, DataEventConstants.PER_NODE_DATA_KEEP_ALIVE_TIME_SECONDS,
perNodeDataHandlerQueue, new ThreadPoolExecutor.DiscardOldestPolicy()); TimeUnit.SECONDS,
perNodeDataHandlerQueue,
new ThreadPoolExecutor.DiscardOldestPolicy());
sharedDataHandlers = new CopyOnWriteArrayList<>(); sharedDataHandlers = new CopyOnWriteArrayList<>();
sharedDataHandlerQueue = new ArrayBlockingQueue<>(DataEventConstants.SHARED_DATA_QUEUE_SIZE); sharedDataHandlerQueue = new ArrayBlockingQueue<>(DataEventConstants.SHARED_DATA_QUEUE_SIZE);
sharedDataEventExecutor = new ThreadPoolExecutor(DataEventConstants.SHARED_DATA_CORE_POOL_SIZE, sharedDataEventExecutor =
new ThreadPoolExecutor(
DataEventConstants.SHARED_DATA_CORE_POOL_SIZE,
DataEventConstants.SHARED_DATA_MAX_POOL_SIZE, DataEventConstants.SHARED_DATA_MAX_POOL_SIZE,
DataEventConstants.SHARED_DATA_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS, DataEventConstants.SHARED_DATA_KEEP_ALIVE_TIME_SECONDS,
sharedDataHandlerQueue, new ThreadPoolExecutor.DiscardOldestPolicy()); TimeUnit.SECONDS,
sharedDataHandlerQueue,
metrics.register(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_SIZE, new ThreadPoolExecutor.DiscardOldestPolicy());
(Gauge<Integer>) () -> perNodeDataHandlers.size());
metrics.register(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE, metrics.register(
(Gauge<Integer>) () -> perNodeDataHandlerQueue.size()); DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_SIZE,
metrics.register(DataEventConstants.SHARED_DATA_SUBSCRIBERS_SIZE, (Gauge<Integer>) () -> perNodeDataHandlers.size());
(Gauge<Integer>) () -> sharedDataHandlers.size()); metrics.register(
metrics.register(DataEventConstants.SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE, DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE,
(Gauge<Integer>) () -> sharedDataHandlerQueue.size()); (Gauge<Integer>) () -> perNodeDataHandlerQueue.size());
metrics.register(
DataEventConstants.SHARED_DATA_SUBSCRIBERS_SIZE,
(Gauge<Integer>) () -> sharedDataHandlers.size());
metrics.register(
DataEventConstants.SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE,
(Gauge<Integer>) () -> sharedDataHandlerQueue.size());
} }
public void notifySharedData(final String key, final Object newValue, final Object oldValue) { public void notifySharedData(final String key, final Object newValue, final Object oldValue) {
sharedDataHandlers.forEach(handler -> sharedDataEventExecutor sharedDataHandlers.forEach(
.execute(() -> handler.onUpdate(key, oldValue, newValue))); handler ->
sharedDataEventExecutor.execute(() -> handler.onUpdate(key, oldValue, newValue)));
} }
public void notifyPerNodeData(final String nodeId, final String key, final Object newValue, public void notifyPerNodeData(
final Object oldValue) { final String nodeId, final String key, final Object newValue, final Object oldValue) {
perNodeDataHandlers.forEach(handler -> perNodeDataEventExecutor perNodeDataHandlers.forEach(
.execute(() -> handler.onUpdate(nodeId, key, oldValue, newValue))); handler ->
perNodeDataEventExecutor.execute(
() -> handler.onUpdate(nodeId, key, oldValue, newValue)));
} }
public void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler) { public void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler) {
perNodeDataHandlers.add(handler); perNodeDataHandlers.add(handler);
} }
public void unregisterPerNodeDataSubscriber(UpdateNodeDataEventHandler handler) { public void unregisterPerNodeDataSubscriber(UpdateNodeDataEventHandler handler) {
perNodeDataHandlers.remove(handler); perNodeDataHandlers.remove(handler);
} }
public int getPerNodeSubscribersSize() { public int getPerNodeSubscribersSize() {
return perNodeDataHandlers.size(); return perNodeDataHandlers.size();
} }
public void registerSharedDataSubscriber(UpdateSharedDataEventHandler handler) { public void registerSharedDataSubscriber(UpdateSharedDataEventHandler handler) {
sharedDataHandlers.add(handler); sharedDataHandlers.add(handler);
} }
public void unregisterSharedDataSubscriber(UpdateSharedDataEventHandler handler) { public void unregisterSharedDataSubscriber(UpdateSharedDataEventHandler handler) {
sharedDataHandlers.remove(handler); sharedDataHandlers.remove(handler);
} }
public int getSharedDataSubscribersSize() { public int getSharedDataSubscribersSize() {
return sharedDataHandlers.size(); return sharedDataHandlers.size();
} }
} }

View File

@ -18,20 +18,19 @@
package org.apache.gossip.event.data; package org.apache.gossip.event.data;
/** /**
* Event handler interface for the per node data items. * Event handler interface for the per node data items. Classes which implement this interface get
* Classes which implement this interface get notifications when per node data item get changed. * notifications when per node data item get changed.
*/ */
public interface UpdateNodeDataEventHandler { public interface UpdateNodeDataEventHandler {
/** /**
* This method get called when a per node datum get changed. * This method get called when a per node datum get changed.
* *
* @param nodeId id of the node that change the value * @param nodeId id of the node that change the value
* @param key key of the datum * @param key key of the datum
* @param oldValue previous value of the datum or null if the datum is discovered * @param oldValue previous value of the datum or null if the datum is discovered for the first
* for the first time * time
* @param newValue updated value of the datum * @param newValue updated value of the datum
*/ */
void onUpdate(String nodeId, String key, Object oldValue, Object newValue); void onUpdate(String nodeId, String key, Object oldValue, Object newValue);
} }

View File

@ -18,17 +18,16 @@
package org.apache.gossip.event.data; package org.apache.gossip.event.data;
/** /**
* Event handler interface for shared data items. * Event handler interface for shared data items. Classes which implement this interface get
* Classes which implement this interface get notifications when shared data get changed. * notifications when shared data get changed.
*/ */
public interface UpdateSharedDataEventHandler { public interface UpdateSharedDataEventHandler {
/** /**
* This method get called when shared data get changed. * This method get called when shared data get changed.
* *
* @param key key of the shared data item * @param key key of the shared data item
* @param oldValue previous value or null if the data is discovered for the first time * @param oldValue previous value or null if the data is discovered for the first time
* @param newValue updated value of the data item * @param newValue updated value of the data item
*/ */
void onUpdate(String key, Object oldValue, Object newValue); void onUpdate(String key, Object oldValue, Object newValue);
} }

View File

@ -20,15 +20,6 @@ package org.apache.gossip.lock;
import com.codahale.metrics.Gauge; import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer; import com.codahale.metrics.Timer;
import org.apache.gossip.Member;
import org.apache.gossip.lock.exceptions.VoteFailedException;
import org.apache.gossip.lock.vote.MajorityVote;
import org.apache.gossip.lock.vote.Vote;
import org.apache.gossip.lock.vote.VoteCandidate;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.SharedDataMessage;
import org.apache.log4j.Logger;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -43,19 +34,27 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.Member;
import org.apache.gossip.lock.exceptions.VoteFailedException;
import org.apache.gossip.lock.vote.MajorityVote;
import org.apache.gossip.lock.vote.Vote;
import org.apache.gossip.lock.vote.VoteCandidate;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.SharedDataMessage;
@Slf4j
public class LockManager { public class LockManager {
public static final Logger LOGGER = Logger.getLogger(LockManager.class);
// For MetricRegistry
public static final String LOCK_KEY_SET_SIZE = "gossip.lock.key_set_size";
public static final String LOCK_TIME = "gossip.lock.time";
private final GossipManager gossipManager; private final GossipManager gossipManager;
private final LockManagerSettings lockSettings; private final LockManagerSettings lockSettings;
private final ScheduledExecutorService voteService; private final ScheduledExecutorService voteService;
private final AtomicInteger numberOfNodes; private final AtomicInteger numberOfNodes;
private final Set<String> lockKeys; private final Set<String> lockKeys;
// For MetricRegistry
public static final String LOCK_KEY_SET_SIZE = "gossip.lock.key_set_size";
public static final String LOCK_TIME = "gossip.lock.time";
private final Timer lockTimeMetric; private final Timer lockTimeMetric;
public LockManager(GossipManager gossipManager, final LockManagerSettings lockManagerSettings, public LockManager(GossipManager gossipManager, final LockManagerSettings lockManagerSettings,
@ -95,20 +94,16 @@ public class LockManager {
long passedCandidates = voteResultMap.values().stream().filter(aBoolean -> aBoolean).count(); long passedCandidates = voteResultMap.values().stream().filter(aBoolean -> aBoolean).count();
String myNodeId = gossipManager.getMyself().getId(); String myNodeId = gossipManager.getMyself().getId();
if (LOGGER.isDebugEnabled()) { log.debug("NodeId=" + myNodeId + ", VoteMap=" + voteResultMap + ", WinnerCount="
LOGGER.debug("NodeId=" + myNodeId + ", VoteMap=" + voteResultMap + ", WinnerCount="
+ passedCandidates); + passedCandidates);
}
// Check for possible dead lock when no candidates were won // Check for possible dead lock when no candidates were won
if (passedCandidates == 0) { if (passedCandidates == 0) {
if (isDeadLock(voteCandidatesMap)) { if (isDeadLock(voteCandidatesMap)) {
deadlockDetectCount++; deadlockDetectCount++;
// Testing for deadlock is not always correct, therefore test for continues deadlocks // Testing for deadlock is not always correct, therefore test for continues deadlocks
if (deadlockDetectCount >= lockSettings.getDeadlockDetectionThreshold()) { if (deadlockDetectCount >= lockSettings.getDeadlockDetectionThreshold()) {
if (LOGGER.isDebugEnabled()) { log.debug("Deadlock detected from node " + myNodeId + ". VoteCandidatesMap="
LOGGER.debug("Deadlock detected from node " + myNodeId + ". VoteCandidatesMap="
+ voteCandidatesMap); + voteCandidatesMap);
}
preventDeadLock(voteCandidatesMap); preventDeadLock(voteCandidatesMap);
} }
} else { } else {
@ -251,9 +246,7 @@ public class LockManager {
} }
} }
} }
if (LOGGER.isDebugEnabled()) { log.debug("Node " + myNodeId + " give up votes to node " + selectedCandidateId);
LOGGER.debug("Node " + myNodeId + " give up votes to node " + selectedCandidateId);
}
} }
private String getVotedCandidateNodeId(String nodeId, private String getVotedCandidateNodeId(String nodeId,

View File

@ -20,9 +20,7 @@ package org.apache.gossip.lock;
import org.apache.gossip.lock.vote.RandomVoteSelector; import org.apache.gossip.lock.vote.RandomVoteSelector;
import org.apache.gossip.lock.vote.VoteSelector; import org.apache.gossip.lock.vote.VoteSelector;
/** /** Stores the lock manager related settings. */
* Stores the lock manager related settings.
*/
public class LockManagerSettings { public class LockManagerSettings {
// Time between vote updates in ms. Default is 1 second. // Time between vote updates in ms. Default is 1 second.
private final int voteUpdateInterval; private final int voteUpdateInterval;
@ -35,30 +33,32 @@ public class LockManagerSettings {
// Wait time between vote result calculation. Default is 1000 // Wait time between vote result calculation. Default is 1000
private final int resultCalculationDelay; private final int resultCalculationDelay;
/**
* Construct LockManagerSettings with default settings.
*/
public static LockManagerSettings getLockManagerDefaultSettings() {
return new LockManagerSettings(1000, new RandomVoteSelector(), -1, 3, 1000);
}
/** /**
* Construct a custom LockManagerSettings * Construct a custom LockManagerSettings
* *
* @param voteUpdateInterval Time between vote updates in milliseconds. * @param voteUpdateInterval Time between vote updates in milliseconds.
* @param voteSelector Vote selection algorithm. Cannot be null * @param voteSelector Vote selection algorithm. Cannot be null
* @param numberOfNodes Number of nodes available for voting. Set to negative value for auto calculate * @param numberOfNodes Number of nodes available for voting. Set to negative value for auto
* calculate
* @param deadlockDetectionThreshold Number of times to test for deadlock before preventing * @param deadlockDetectionThreshold Number of times to test for deadlock before preventing
* @param resultCalculationDelay Wait time between vote result calculation * @param resultCalculationDelay Wait time between vote result calculation
*/ */
public LockManagerSettings(int voteUpdateInterval, VoteSelector voteSelector, int numberOfNodes, public LockManagerSettings(
int deadlockDetectionThreshold, int resultCalculationDelay) { int voteUpdateInterval,
VoteSelector voteSelector,
int numberOfNodes,
int deadlockDetectionThreshold,
int resultCalculationDelay) {
this.voteUpdateInterval = voteUpdateInterval; this.voteUpdateInterval = voteUpdateInterval;
this.voteSelector = voteSelector; this.voteSelector = voteSelector;
this.numberOfNodes = numberOfNodes; this.numberOfNodes = numberOfNodes;
this.deadlockDetectionThreshold = deadlockDetectionThreshold; this.deadlockDetectionThreshold = deadlockDetectionThreshold;
this.resultCalculationDelay = resultCalculationDelay; this.resultCalculationDelay = resultCalculationDelay;
}
/** Construct LockManagerSettings with default settings. */
public static LockManagerSettings getLockManagerDefaultSettings() {
return new LockManagerSettings(1000, new RandomVoteSelector(), -1, 3, 1000);
} }
public int getVoteUpdateInterval() { public int getVoteUpdateInterval() {

View File

@ -17,9 +17,7 @@
*/ */
package org.apache.gossip.lock.exceptions; package org.apache.gossip.lock.exceptions;
/** /** This exception is thrown when the lock based voting is failed. */
* This exception is thrown when the lock based voting is failed.
*/
public class VoteFailedException extends Exception { public class VoteFailedException extends Exception {
/** /**
* Constructs a new VoteFailedException with the specified detail message. * Constructs a new VoteFailedException with the specified detail message.
@ -31,11 +29,10 @@ public class VoteFailedException extends Exception {
} }
/** /**
* Constructs a new VoteFailedException with the specified detail message and * Constructs a new VoteFailedException with the specified detail message and cause.
* cause.
* *
* @param message the detail message * @param message the detail message
* @param cause the cause for this exception * @param cause the cause for this exception
*/ */
public VoteFailedException(String message, Throwable cause) { public VoteFailedException(String message, Throwable cause) {
super(message, cause); super(message, cause);

View File

@ -17,14 +17,13 @@
*/ */
package org.apache.gossip.lock.vote; package org.apache.gossip.lock.vote;
import org.apache.gossip.crdt.Crdt;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.gossip.crdt.Crdt;
/** /**
* CRDT which used for distribute a votes for a given key. * CRDT which used for distribute a votes for a given key.

View File

@ -22,9 +22,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
/** /** VoteSelector implementation which randomly select a voting node. */
* VoteSelector implementation which randomly select a voting node.
*/
public class RandomVoteSelector implements VoteSelector { public class RandomVoteSelector implements VoteSelector {
@Override @Override

View File

@ -25,9 +25,9 @@ import java.util.List;
public class Vote { public class Vote {
private final String votingNode; private final String votingNode;
private final Boolean voteValue; // TODO: 7/16/17 weight? private final Boolean voteValue; // TODO: 7/16/17 weight?
private Boolean voteExchange;
private final List<String> liveMembers; private final List<String> liveMembers;
private final List<String> deadMembers; private final List<String> deadMembers;
private Boolean voteExchange;
public Vote(String votingNode, Boolean voteValue, Boolean voteExchange, List<String> liveMembers, public Vote(String votingNode, Boolean voteValue, Boolean voteExchange, List<String> liveMembers,
List<String> deadMembers) { List<String> deadMembers) {

View File

@ -20,9 +20,7 @@ package org.apache.gossip.lock.vote;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /** Stores the vote candidate details and its votes. */
* Stores the vote candidate details and its votes.
*/
public class VoteCandidate { public class VoteCandidate {
private final String candidateNodeId; private final String candidateNodeId;
@ -59,13 +57,11 @@ public class VoteCandidate {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof VoteCandidate)) if (!(obj instanceof VoteCandidate)) return false;
return false; if (obj == this) return true;
if (obj == this)
return true;
VoteCandidate other = (VoteCandidate) obj; VoteCandidate other = (VoteCandidate) obj;
return this.candidateNodeId.equals(other.candidateNodeId) && this.votingKey return this.candidateNodeId.equals(other.candidateNodeId)
.equals(other.votingKey); && this.votingKey.equals(other.votingKey);
} }
@Override @Override

View File

@ -19,12 +19,11 @@ package org.apache.gossip.lock.vote;
import java.util.Set; import java.util.Set;
/** /** This interface defines vote selection algorithm for the vote based locking. */
* This interface defines vote selection algorithm for the vote based locking.
*/
public interface VoteSelector { public interface VoteSelector {
/** /**
* This method get call by the lock manager of a node to decide which candidate need to be choose for voting. * This method get call by the lock manager of a node to decide which candidate need to be choose
* for voting.
* *
* @param voteCandidateIds node id set for the vote candidates * @param voteCandidateIds node id set for the vote candidates
* @return selected node id to vote from the given vote candidate set. * @return selected node id to vote from the given vote candidate set.

View File

@ -17,33 +17,32 @@
*/ */
package org.apache.gossip.manager; package org.apache.gossip.manager;
import java.util.Map.Entry; import static com.codahale.metrics.MetricRegistry.name;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.MetricRegistry;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.codahale.metrics.Histogram; import lombok.extern.slf4j.Slf4j;
import com.codahale.metrics.MetricRegistry;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.model.ActiveGossipOk; import org.apache.gossip.model.ActiveGossipOk;
import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.Member; import org.apache.gossip.model.Member;
import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.Response; import org.apache.gossip.model.Response;
import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.model.ShutdownMessage;
import org.apache.gossip.udp.*; import org.apache.gossip.udp.*;
import org.apache.log4j.Logger;
import static com.codahale.metrics.MetricRegistry.name;
/** /**
* The ActiveGossipThread sends information. Pick a random partner and send the membership list to that partner * The ActiveGossipThread sends information. Pick a random partner and send the membership list to that partner
*/ */
@Slf4j
public abstract class AbstractActiveGossiper { public abstract class AbstractActiveGossiper {
protected static final Logger LOGGER = Logger.getLogger(AbstractActiveGossiper.class);
protected final GossipManager gossipManager; protected final GossipManager gossipManager;
protected final GossipCore gossipCore; protected final GossipCore gossipCore;
private final Histogram sharedDataHistogram; private final Histogram sharedDataHistogram;
@ -128,7 +127,7 @@ public abstract class AbstractActiveGossiper {
udpMessage.setUriFrom(me.getId()); udpMessage.setUriFrom(me.getId());
} }
} }
if (udpMessage.getMessages().size() > 0) { if (!udpMessage.getMessages().isEmpty()) {
gossipCore.sendOneWay(udpMessage, member.getUri()); gossipCore.sendOneWay(udpMessage, member.getUri());
} }
} }
@ -229,7 +228,7 @@ public abstract class AbstractActiveGossiper {
if (r instanceof ActiveGossipOk){ if (r instanceof ActiveGossipOk){
//maybe count metrics here //maybe count metrics here
} else { } else {
LOGGER.debug("Message " + message + " generated response " + r); log.debug("Message " + message + " generated response " + r);
} }
sendMembershipHistogram.update(System.currentTimeMillis() - startTime); sendMembershipHistogram.update(System.currentTimeMillis() - startTime);
} }
@ -252,7 +251,7 @@ public abstract class AbstractActiveGossiper {
*/ */
protected LocalMember selectPartner(List<LocalMember> memberList) { protected LocalMember selectPartner(List<LocalMember> memberList) {
LocalMember member = null; LocalMember member = null;
if (memberList.size() > 0) { if (!memberList.isEmpty()) {
int randomNeighborIndex = random.nextInt(memberList.size()); int randomNeighborIndex = random.nextInt(memberList.size());
member = memberList.get(randomNeighborIndex); member = memberList.get(randomNeighborIndex);
} }

View File

@ -20,6 +20,6 @@ package org.apache.gossip.manager;
public interface Clock { public interface Clock {
long currentTimeMillis(); long currentTimeMillis();
long nanoTime(); long nanoTime();
} }

View File

@ -22,7 +22,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.model.SharedDataMessage;

View File

@ -17,20 +17,19 @@
*/ */
package org.apache.gossip.manager; package org.apache.gossip.manager;
import java.util.List; import com.codahale.metrics.MetricRegistry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import com.codahale.metrics.MetricRegistry;
/** /**
* Sends gossip traffic at different rates to other racks and data-centers. * Sends gossip traffic at different rates to other racks and data-centers.
* This implementation controls the rate at which gossip traffic is shared. * This implementation controls the rate at which gossip traffic is shared.
@ -38,18 +37,17 @@ import com.codahale.metrics.MetricRegistry;
* in the rack than in the the datacenter. We can adjust the rate at which we send messages to each group. * in the rack than in the the datacenter. We can adjust the rate at which we send messages to each group.
* *
*/ */
@Slf4j
public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper { public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
public static final String DATACENTER = "datacenter"; public static final String DATACENTER = "datacenter";
public static final String RACK = "rack"; public static final String RACK = "rack";
private final BlockingQueue<Runnable> workQueue;
private int sameRackGossipIntervalMs = 100; private int sameRackGossipIntervalMs = 100;
private int sameDcGossipIntervalMs = 500; private int sameDcGossipIntervalMs = 500;
private int differentDatacenterGossipIntervalMs = 1000; private int differentDatacenterGossipIntervalMs = 1000;
private int randomDeadMemberSendIntervalMs = 250; private int randomDeadMemberSendIntervalMs = 250;
private ScheduledExecutorService scheduledExecutorService; private ScheduledExecutorService scheduledExecutorService;
private final BlockingQueue<Runnable> workQueue;
private ThreadPoolExecutor threadService; private ThreadPoolExecutor threadService;
public DatacenterRackAwareActiveGossiper(GossipManager gossipManager, GossipCore gossipCore, public DatacenterRackAwareActiveGossiper(GossipManager gossipManager, GossipCore gossipCore,
@ -220,14 +218,14 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
try { try {
scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS); scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.debug("Issue during shutdown", e); log.debug("Issue during shutdown", e);
} }
sendShutdownMessage(); sendShutdownMessage();
threadService.shutdown(); threadService.shutdown();
try { try {
threadService.awaitTermination(5, TimeUnit.SECONDS); threadService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.debug("Issue during shutdown", e); log.debug("Issue during shutdown", e);
} }
} }

View File

@ -20,6 +20,13 @@ package org.apache.gossip.manager;
import com.codahale.metrics.Gauge; import com.codahale.metrics.Gauge;
import com.codahale.metrics.Meter; import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.*;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.Member; import org.apache.gossip.Member;
import org.apache.gossip.RemoteMember; import org.apache.gossip.RemoteMember;
@ -33,35 +40,20 @@ import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.Response; import org.apache.gossip.model.Response;
import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.udp.Trackable; import org.apache.gossip.udp.Trackable;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.*;
@Slf4j
public class GossipCore implements GossipCoreConstants { public class GossipCore implements GossipCoreConstants {
class LatchAndBase {
private final CountDownLatch latch;
private volatile Base base;
LatchAndBase(){
latch = new CountDownLatch(1);
}
}
public static final Logger LOGGER = Logger.getLogger(GossipCore.class);
private final GossipManager gossipManager; private final GossipManager gossipManager;
private ConcurrentHashMap<String, LatchAndBase> requests; @Getter
private final ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> perNodeData; private final ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> perNodeData;
@Getter
private final ConcurrentHashMap<String, SharedDataMessage> sharedData; private final ConcurrentHashMap<String, SharedDataMessage> sharedData;
private final Meter messageSerdeException; private final Meter messageSerdeException;
private final Meter transmissionException; private final Meter transmissionException;
private final Meter transmissionSuccess; private final Meter transmissionSuccess;
private final DataEventManager eventManager; private final DataEventManager eventManager;
private ConcurrentHashMap<String, LatchAndBase> requests;
public GossipCore(GossipManager manager, MetricRegistry metrics){ public GossipCore(GossipManager manager, MetricRegistry metrics){
this.gossipManager = manager; this.gossipManager = manager;
requests = new ConcurrentHashMap<>(); requests = new ConcurrentHashMap<>();
@ -75,7 +67,7 @@ public class GossipCore implements GossipCoreConstants {
transmissionException = metrics.meter(MESSAGE_TRANSMISSION_EXCEPTION); transmissionException = metrics.meter(MESSAGE_TRANSMISSION_EXCEPTION);
transmissionSuccess = metrics.meter(MESSAGE_TRANSMISSION_SUCCESS); transmissionSuccess = metrics.meter(MESSAGE_TRANSMISSION_SUCCESS);
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public void addSharedData(SharedDataMessage message) { public void addSharedData(SharedDataMessage message) {
while (true){ while (true){
@ -135,20 +127,12 @@ public class GossipCore implements GossipCoreConstants {
} }
} }
public ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> getPerNodeData(){
return perNodeData;
}
public ConcurrentHashMap<String, SharedDataMessage> getSharedData() {
return sharedData;
}
public void shutdown(){ public void shutdown(){
} }
public void receive(Base base) { public void receive(Base base) {
if (!gossipManager.getMessageHandler().invoke(this, gossipManager, base)) { if (!gossipManager.getMessageHandler().invoke(this, gossipManager, base)) {
LOGGER.warn("received message can not be handled"); log.warn("received message can not be handled");
} }
} }
@ -177,10 +161,8 @@ public class GossipCore implements GossipCoreConstants {
} }
public Response send(Base message, URI uri){ public Response send(Base message, URI uri){
if (LOGGER.isDebugEnabled()){ log.debug("Sending " + message);
LOGGER.debug("Sending " + message); log.debug("Current request queue " + requests);
LOGGER.debug("Current request queue " + requests);
}
final Trackable t; final Trackable t;
LatchAndBase latchAndBase = null; LatchAndBase latchAndBase = null;
@ -195,7 +177,7 @@ public class GossipCore implements GossipCoreConstants {
if (latchAndBase == null){ if (latchAndBase == null){
return null; return null;
} }
try { try {
boolean complete = latchAndBase.latch.await(1, TimeUnit.SECONDS); boolean complete = latchAndBase.latch.await(1, TimeUnit.SECONDS);
if (complete){ if (complete){
@ -206,9 +188,7 @@ public class GossipCore implements GossipCoreConstants {
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
if (latchAndBase != null){
requests.remove(t.getUuid() + "/" + t.getUriFrom()); requests.remove(t.getUuid() + "/" + t.getUriFrom());
}
} }
} }
@ -222,7 +202,7 @@ public class GossipCore implements GossipCoreConstants {
try { try {
sendInternal(message, u); sendInternal(message, u);
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
LOGGER.debug("Send one way failed", ex); log.debug("Send one way failed", ex);
} }
} }
@ -240,12 +220,12 @@ public class GossipCore implements GossipCoreConstants {
* *
*/ */
public void mergeLists(RemoteMember senderMember, List<Member> remoteList) { public void mergeLists(RemoteMember senderMember, List<Member> remoteList) {
if (LOGGER.isDebugEnabled()){ if (log.isDebugEnabled()){
debugState(senderMember, remoteList); debugState(senderMember, remoteList);
} }
for (LocalMember i : gossipManager.getDeadMembers()) { for (LocalMember i : gossipManager.getDeadMembers()) {
if (i.getId().equals(senderMember.getId())) { if (i.getId().equals(senderMember.getId())) {
LOGGER.debug(gossipManager.getMyself() + " contacted by dead member " + senderMember.getUri()); log.debug(gossipManager.getMyself() + " contacted by dead member " + senderMember.getUri());
i.recordHeartbeat(senderMember.getHeartbeat()); i.recordHeartbeat(senderMember.getHeartbeat());
i.setHeartbeat(senderMember.getHeartbeat()); i.setHeartbeat(senderMember.getHeartbeat());
//TODO consider forcing an UP here //TODO consider forcing an UP here
@ -275,14 +255,14 @@ public class GossipCore implements GossipCoreConstants {
} }
} }
} }
if (LOGGER.isDebugEnabled()){ if (log.isDebugEnabled()){
debugState(senderMember, remoteList); debugState(senderMember, remoteList);
} }
} }
private void debugState(RemoteMember senderMember, private void debugState(RemoteMember senderMember,
List<Member> remoteList){ List<Member> remoteList){
LOGGER.warn( log.warn(
"-----------------------\n" + "-----------------------\n" +
"Me " + gossipManager.getMyself() + "\n" + "Me " + gossipManager.getMyself() + "\n" +
"Sender " + senderMember + "\n" + "Sender " + senderMember + "\n" +
@ -313,7 +293,7 @@ public class GossipCore implements GossipCoreConstants {
} }
} }
} }
void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler){ void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler){
eventManager.registerPerNodeDataSubscriber(handler); eventManager.registerPerNodeDataSubscriber(handler);
} }
@ -329,4 +309,14 @@ public class GossipCore implements GossipCoreConstants {
void unregisterSharedDataSubscriber(UpdateSharedDataEventHandler handler){ void unregisterSharedDataSubscriber(UpdateSharedDataEventHandler handler){
eventManager.unregisterSharedDataSubscriber(handler); eventManager.unregisterSharedDataSubscriber(handler);
} }
class LatchAndBase {
private final CountDownLatch latch;
private volatile Base base;
LatchAndBase(){
latch = new CountDownLatch(1);
}
}
} }

View File

@ -18,7 +18,7 @@
package org.apache.gossip.manager; package org.apache.gossip.manager;
public interface GossipCoreConstants { public interface GossipCoreConstants {
String PER_NODE_DATA_SIZE = "gossip.core.pernodedata.size"; String PER_NODE_DATA_SIZE = "gossip.core.pernodedata.size";
String SHARED_DATA_SIZE = "gossip.core.shareddata.size"; String SHARED_DATA_SIZE = "gossip.core.shareddata.size";
String REQUEST_SIZE = "gossip.core.requests.size"; String REQUEST_SIZE = "gossip.core.requests.size";
String THREADPOOL_ACTIVE = "gossip.core.threadpool.active"; String THREADPOOL_ACTIVE = "gossip.core.threadpool.active";

View File

@ -20,6 +20,22 @@ package org.apache.gossip.manager;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.Serial;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.Member; import org.apache.gossip.Member;
@ -36,29 +52,14 @@ import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.protocol.ProtocolManager; import org.apache.gossip.protocol.ProtocolManager;
import org.apache.gossip.transport.TransportManager; import org.apache.gossip.transport.TransportManager;
import org.apache.gossip.utils.ReflectionUtils; import org.apache.gossip.utils.ReflectionUtils;
import org.apache.log4j.Logger;
import java.io.File; @Slf4j
import java.net.URI; public class GossipManager {
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
public abstract class GossipManager {
public static final Logger LOGGER = Logger.getLogger(GossipManager.class);
// this mapper is used for ring and user-data persistence only. NOT messages. // this mapper is used for ring and user-data persistence only. NOT messages.
public static final ObjectMapper metdataObjectMapper = new ObjectMapper() { public static final ObjectMapper metdataObjectMapper = new ObjectMapper() {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
{ {
enableDefaultTyping(); enableDefaultTyping();
@ -69,10 +70,6 @@ public abstract class GossipManager {
private final LocalMember me; private final LocalMember me;
private final GossipSettings settings; private final GossipSettings settings;
private final AtomicBoolean gossipServiceRunning; private final AtomicBoolean gossipServiceRunning;
private TransportManager transportManager;
private ProtocolManager protocolManager;
private final GossipCore gossipCore; private final GossipCore gossipCore;
private final DataReaper dataReaper; private final DataReaper dataReaper;
private final Clock clock; private final Clock clock;
@ -81,9 +78,10 @@ public abstract class GossipManager {
private final RingStatePersister ringState; private final RingStatePersister ringState;
private final UserDataPersister userDataState; private final UserDataPersister userDataState;
private final GossipMemberStateRefresher memberStateRefresher; private final GossipMemberStateRefresher memberStateRefresher;
private final MessageHandler messageHandler; private final MessageHandler messageHandler;
private final LockManager lockManager; private final LockManager lockManager;
private TransportManager transportManager;
private ProtocolManager protocolManager;
public GossipManager(String cluster, public GossipManager(String cluster,
URI uri, String id, Map<String, String> properties, GossipSettings settings, URI uri, String id, Map<String, String> properties, GossipSettings settings,
@ -122,6 +120,21 @@ public abstract class GossipManager {
readSavedDataState(); readSavedDataState();
} }
public static File buildRingStatePath(GossipManager manager) {
return new File(manager.getSettings().getPathToRingState(), "ringstate." + manager.getMyself().getClusterName() + "."
+ manager.getMyself().getId() + ".json");
}
public static File buildSharedDataPath(GossipManager manager){
return new File(manager.getSettings().getPathToDataState(), "shareddata."
+ manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json");
}
public static File buildPerNodeDataPath(GossipManager manager) {
return new File(manager.getSettings().getPathToDataState(), "pernodedata."
+ manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json");
}
public MessageHandler getMessageHandler() { public MessageHandler getMessageHandler() {
return messageHandler; return messageHandler;
} }
@ -144,7 +157,7 @@ public abstract class GossipManager {
.filter(entry -> GossipState.DOWN.equals(entry.getValue())) .filter(entry -> GossipState.DOWN.equals(entry.getValue()))
.map(Entry::getKey).collect(Collectors.toList())); .map(Entry::getKey).collect(Collectors.toList()));
} }
/** /**
* *
* @return a read only list of members found in the UP state * @return a read only list of members found in the UP state
@ -166,26 +179,26 @@ public abstract class GossipManager {
* thread and start the receiver thread. * thread and start the receiver thread.
*/ */
public void init() { public void init() {
// protocol manager and transport managers are specified in settings. // protocol manager and transport managers are specified in settings.
// construct them here via reflection. // construct them here via reflection.
protocolManager = ReflectionUtils.constructWithReflection( protocolManager = ReflectionUtils.constructWithReflection(
settings.getProtocolManagerClass(), settings.getProtocolManagerClass(),
new Class<?>[] { GossipSettings.class, String.class, MetricRegistry.class }, new Class<?>[] { GossipSettings.class, String.class, MetricRegistry.class },
new Object[] { settings, me.getId(), this.getRegistry() } new Object[] { settings, me.getId(), this.getRegistry() }
); );
transportManager = ReflectionUtils.constructWithReflection( transportManager = ReflectionUtils.constructWithReflection(
settings.getTransportManagerClass(), settings.getTransportManagerClass(),
new Class<?>[] { GossipManager.class, GossipCore.class}, new Class<?>[] { GossipManager.class, GossipCore.class},
new Object[] { this, gossipCore } new Object[] { this, gossipCore }
); );
// start processing gossip messages. // start processing gossip messages.
transportManager.startEndpoint(); transportManager.startEndpoint();
transportManager.startActiveGossiper(); transportManager.startActiveGossiper();
dataReaper.init(); dataReaper.init();
if (settings.isPersistRingState()) { if (settings.isPersistRingState()) {
scheduledServiced.scheduleAtFixedRate(ringState, 60, 60, TimeUnit.SECONDS); scheduledServiced.scheduleAtFixedRate(ringState, 60, 60, TimeUnit.SECONDS);
@ -194,9 +207,9 @@ public abstract class GossipManager {
scheduledServiced.scheduleAtFixedRate(userDataState, 60, 60, TimeUnit.SECONDS); scheduledServiced.scheduleAtFixedRate(userDataState, 60, 60, TimeUnit.SECONDS);
} }
memberStateRefresher.init(); memberStateRefresher.init();
LOGGER.debug("The GossipManager is started."); log.debug("The GossipManager is started.");
} }
private void readSavedRingState() { private void readSavedRingState() {
if (settings.isPersistRingState()) { if (settings.isPersistRingState()) {
for (LocalMember l : ringState.readFromDisk()) { for (LocalMember l : ringState.readFromDisk()) {
@ -238,7 +251,7 @@ public abstract class GossipManager {
try { try {
scheduledServiced.awaitTermination(1, TimeUnit.SECONDS); scheduledServiced.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.error(e); log.error("Error!", e);
} }
scheduledServiced.shutdownNow(); scheduledServiced.shutdownNow();
} }
@ -331,34 +344,19 @@ public abstract class GossipManager {
public Clock getClock() { public Clock getClock() {
return clock; return clock;
} }
public MetricRegistry getRegistry() {
return registry;
}
public ProtocolManager getProtocolManager() {
return protocolManager;
}
public TransportManager getTransportManager() {
return transportManager;
}
// todo: consider making these path methods part of GossipSettings // todo: consider making these path methods part of GossipSettings
public static File buildRingStatePath(GossipManager manager) { public MetricRegistry getRegistry() {
return new File(manager.getSettings().getPathToRingState(), "ringstate." + manager.getMyself().getClusterName() + "." return registry;
+ manager.getMyself().getId() + ".json");
} }
public static File buildSharedDataPath(GossipManager manager){ public ProtocolManager getProtocolManager() {
return new File(manager.getSettings().getPathToDataState(), "shareddata." return protocolManager;
+ manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json");
} }
public static File buildPerNodeDataPath(GossipManager manager) { public TransportManager getTransportManager() {
return new File(manager.getSettings().getPathToDataState(), "pernodedata." return transportManager;
+ manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json");
} }
public void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler){ public void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler){

View File

@ -46,7 +46,7 @@ public class GossipManagerBuilder {
private List<Member> gossipMembers; private List<Member> gossipMembers;
private GossipListener listener; private GossipListener listener;
private MetricRegistry registry; private MetricRegistry registry;
private Map<String,String> properties; private Map<String, String> properties;
private MessageHandler messageHandler; private MessageHandler messageHandler;
private ManagerBuilder() {} private ManagerBuilder() {}
@ -61,8 +61,8 @@ public class GossipManagerBuilder {
this.cluster = cluster; this.cluster = cluster;
return this; return this;
} }
public ManagerBuilder properties(Map<String,String> properties) { public ManagerBuilder properties(Map<String, String> properties) {
this.properties = properties; this.properties = properties;
return this; return this;
} }
@ -76,7 +76,7 @@ public class GossipManagerBuilder {
this.settings = settings; this.settings = settings;
return this; return this;
} }
public ManagerBuilder startupSettings(StartupSettings startupSettings) { public ManagerBuilder startupSettings(StartupSettings startupSettings) {
this.cluster = startupSettings.getCluster(); this.cluster = startupSettings.getCluster();
this.id = startupSettings.getId(); this.id = startupSettings.getId();
@ -95,13 +95,13 @@ public class GossipManagerBuilder {
this.listener = listener; this.listener = listener;
return this; return this;
} }
public ManagerBuilder registry(MetricRegistry registry) { public ManagerBuilder registry(MetricRegistry registry) {
this.registry = registry; this.registry = registry;
return this; return this;
} }
public ManagerBuilder uri(URI uri){ public ManagerBuilder uri(URI uri) {
this.uri = uri; this.uri = uri;
return this; return this;
} }
@ -116,24 +116,32 @@ public class GossipManagerBuilder {
checkArgument(cluster != null, "You must specify a cluster name"); checkArgument(cluster != null, "You must specify a cluster name");
checkArgument(settings != null, "You must specify gossip settings"); checkArgument(settings != null, "You must specify gossip settings");
checkArgument(uri != null, "You must specify a uri"); checkArgument(uri != null, "You must specify a uri");
if (registry == null){ if (registry == null) {
registry = new MetricRegistry(); registry = new MetricRegistry();
} }
if (properties == null){ if (properties == null) {
properties = new HashMap<String,String>(); properties = new HashMap<String, String>();
} }
if (listener == null){ if (listener == null) {
listener((a,b) -> {}); listener((a, b) -> {});
} }
if (gossipMembers == null) { if (gossipMembers == null) {
gossipMembers = new ArrayList<>(); gossipMembers = new ArrayList<>();
} }
if (messageHandler == null) { if (messageHandler == null) {
messageHandler = MessageHandlerFactory.defaultHandler(); messageHandler = MessageHandlerFactory.defaultHandler();
} }
return new GossipManager(cluster, uri, id, properties, settings, gossipMembers, listener, registry, messageHandler) {} ; return new GossipManager(
cluster,
uri,
id,
properties,
settings,
gossipMembers,
listener,
registry,
messageHandler) {};
} }
} }
} }

View File

@ -18,22 +18,21 @@
package org.apache.gossip.manager; package org.apache.gossip.manager;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.*;
import java.util.function.BiFunction;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.event.GossipListener; import org.apache.gossip.event.GossipListener;
import org.apache.gossip.event.GossipState; import org.apache.gossip.event.GossipState;
import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.model.ShutdownMessage;
import org.apache.log4j.Logger;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.*;
import java.util.function.BiFunction;
@Slf4j
public class GossipMemberStateRefresher { public class GossipMemberStateRefresher {
public static final Logger LOGGER = Logger.getLogger(GossipMemberStateRefresher.class);
private final Map<LocalMember, GossipState> members; private final Map<LocalMember, GossipState> members;
private final GossipSettings settings; private final GossipSettings settings;
@ -66,7 +65,7 @@ public class GossipMemberStateRefresher {
try { try {
runOnce(); runOnce();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
LOGGER.warn("scheduled state had exception", ex); log.warn("scheduled state had exception", ex);
} }
} }
@ -144,13 +143,13 @@ public class GossipMemberStateRefresher {
try { try {
scheduledExecutor.awaitTermination(5, TimeUnit.SECONDS); scheduledExecutor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.debug("Issue during shutdown", e); log.debug("Issue during shutdown", e);
} }
listenerExecutor.shutdown(); listenerExecutor.shutdown();
try { try {
listenerExecutor.awaitTermination(5, TimeUnit.SECONDS); listenerExecutor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.debug("Issue during shutdown", e); log.debug("Issue during shutdown", e);
} }
listenerExecutor.shutdownNow(); listenerExecutor.shutdownNow();
} }

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.gossip.manager; package org.apache.gossip.manager;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -24,14 +25,12 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.NavigableSet; import java.util.NavigableSet;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import org.apache.log4j.Logger;
@Slf4j
public class RingStatePersister implements Runnable { public class RingStatePersister implements Runnable {
private static final Logger LOGGER = Logger.getLogger(RingStatePersister.class);
private final File path; private final File path;
// NOTE: this is a different instance than what gets used for message marshalling. // NOTE: this is a different instance than what gets used for message marshalling.
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
@ -53,7 +52,7 @@ public class RingStatePersister implements Runnable {
try (FileOutputStream fos = new FileOutputStream(path)){ try (FileOutputStream fos = new FileOutputStream(path)){
objectMapper.writeValue(fos, i); objectMapper.writeValue(fos, i);
} catch (IOException e) { } catch (IOException e) {
LOGGER.debug(e); log.error("Error!", e);
} }
} }
@ -65,7 +64,7 @@ public class RingStatePersister implements Runnable {
try (FileInputStream fos = new FileInputStream(path)){ try (FileInputStream fos = new FileInputStream(path)){
return objectMapper.readValue(fos, ArrayList.class); return objectMapper.readValue(fos, ArrayList.class);
} catch (IOException e) { } catch (IOException e) {
LOGGER.debug(e); log.error("Error", e);
} }
return new ArrayList<>(); return new ArrayList<>();
} }

View File

@ -25,50 +25,60 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.LocalMember; import org.apache.gossip.LocalMember;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
/** /** Base implementation gossips randomly to live nodes periodically gossips to dead ones */
* Base implementation gossips randomly to live nodes periodically gossips to dead ones @Slf4j
*
*/
public class SimpleActiveGossiper extends AbstractActiveGossiper { public class SimpleActiveGossiper extends AbstractActiveGossiper {
private ScheduledExecutorService scheduledExecutorService;
private final BlockingQueue<Runnable> workQueue; private final BlockingQueue<Runnable> workQueue;
private ScheduledExecutorService scheduledExecutorService;
private ThreadPoolExecutor threadService; private ThreadPoolExecutor threadService;
public SimpleActiveGossiper(GossipManager gossipManager, GossipCore gossipCore, public SimpleActiveGossiper(
MetricRegistry registry) { GossipManager gossipManager, GossipCore gossipCore, MetricRegistry registry) {
super(gossipManager, gossipCore, registry); super(gossipManager, gossipCore, registry);
scheduledExecutorService = Executors.newScheduledThreadPool(2); scheduledExecutorService = Executors.newScheduledThreadPool(2);
workQueue = new ArrayBlockingQueue<Runnable>(1024); workQueue = new ArrayBlockingQueue<Runnable>(1024);
threadService = new ThreadPoolExecutor(1, 30, 1, TimeUnit.SECONDS, workQueue, threadService =
new ThreadPoolExecutor.DiscardOldestPolicy()); new ThreadPoolExecutor(
1, 30, 1, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.DiscardOldestPolicy());
} }
@Override @Override
public void init() { public void init() {
super.init(); super.init();
scheduledExecutorService.scheduleAtFixedRate(() -> {
threadService.execute(() -> {
sendToALiveMember();
});
}, 0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate(() -> {
sendToDeadMember();
}, 0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate( scheduledExecutorService.scheduleAtFixedRate(
() -> sendPerNodeData(gossipManager.getMyself(), () -> {
selectPartner(gossipManager.getLiveMembers())), threadService.execute(this::sendToALiveMember);
0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS); },
0,
gossipManager.getSettings().getGossipInterval(),
TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate( scheduledExecutorService.scheduleAtFixedRate(
() -> sendSharedData(gossipManager.getMyself(), this::sendToDeadMember,
selectPartner(gossipManager.getLiveMembers())), 0,
0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS); gossipManager.getSettings().getGossipInterval(),
TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate(
() ->
sendPerNodeData(
gossipManager.getMyself(), selectPartner(gossipManager.getLiveMembers())),
0,
gossipManager.getSettings().getGossipInterval(),
TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate(
() ->
sendSharedData(
gossipManager.getMyself(), selectPartner(gossipManager.getLiveMembers())),
0,
gossipManager.getSettings().getGossipInterval(),
TimeUnit.MILLISECONDS);
} }
@Override @Override
public void shutdown() { public void shutdown() {
super.shutdown(); super.shutdown();
@ -76,31 +86,29 @@ public class SimpleActiveGossiper extends AbstractActiveGossiper {
try { try {
scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS); scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.debug("Issue during shutdown", e); log.debug("Issue during shutdown", e);
} }
sendShutdownMessage(); sendShutdownMessage();
threadService.shutdown(); threadService.shutdown();
try { try {
threadService.awaitTermination(5, TimeUnit.SECONDS); threadService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.debug("Issue during shutdown", e); log.debug("Issue during shutdown", e);
} }
} }
protected void sendToALiveMember(){ protected void sendToALiveMember() {
LocalMember member = selectPartner(gossipManager.getLiveMembers()); LocalMember member = selectPartner(gossipManager.getLiveMembers());
sendMembershipList(gossipManager.getMyself(), member); sendMembershipList(gossipManager.getMyself(), member);
} }
protected void sendToDeadMember(){ protected void sendToDeadMember() {
LocalMember member = selectPartner(gossipManager.getDeadMembers()); LocalMember member = selectPartner(gossipManager.getDeadMembers());
sendMembershipList(gossipManager.getMyself(), member); sendMembershipList(gossipManager.getMyself(), member);
} }
/** /** sends an optimistic shutdown message to several clusters nodes */
* sends an optimistic shutdown message to several clusters nodes protected void sendShutdownMessage() {
*/
protected void sendShutdownMessage(){
List<LocalMember> l = gossipManager.getLiveMembers(); List<LocalMember> l = gossipManager.getLiveMembers();
int sendTo = l.size() < 3 ? 1 : l.size() / 2; int sendTo = l.size() < 3 ? 1 : l.size() / 2;
for (int i = 0; i < sendTo; i++) { for (int i = 0; i < sendTo; i++) {

View File

@ -28,5 +28,4 @@ public class SystemClock implements Clock {
public long nanoTime() { public long nanoTime() {
return System.nanoTime(); return System.nanoTime();
} }
} }

View File

@ -14,7 +14,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.gossip.manager; package org.apache.gossip.manager;
import java.io.File; import java.io.File;
@ -24,71 +24,70 @@ import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.log4j.Logger;
@Slf4j
public class UserDataPersister implements Runnable { public class UserDataPersister implements Runnable {
private static final Logger LOGGER = Logger.getLogger(UserDataPersister.class); private final GossipCore gossipCore;
private final GossipCore gossipCore;
private final File perNodePath; private final File perNodePath;
private final File sharedPath; private final File sharedPath;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
UserDataPersister(GossipCore gossipCore, File perNodePath, File sharedPath) { UserDataPersister(GossipCore gossipCore, File perNodePath, File sharedPath) {
this.gossipCore = gossipCore; this.gossipCore = gossipCore;
this.objectMapper = GossipManager.metdataObjectMapper; this.objectMapper = GossipManager.metdataObjectMapper;
this.perNodePath = perNodePath; this.perNodePath = perNodePath;
this.sharedPath = sharedPath; this.sharedPath = sharedPath;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> readPerNodeFromDisk(){ ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> readPerNodeFromDisk() {
if (!perNodePath.exists()) { if (!perNodePath.exists()) {
return new ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>>(); return new ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>>();
} }
try (FileInputStream fos = new FileInputStream(perNodePath)){ try (FileInputStream fos = new FileInputStream(perNodePath)) {
return objectMapper.readValue(fos, ConcurrentHashMap.class); return objectMapper.readValue(fos, ConcurrentHashMap.class);
} catch (IOException e) { } catch (IOException e) {
LOGGER.debug(e); log.error("Error!", e);
} }
return new ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>>(); return new ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>>();
} }
void writePerNodeToDisk(){ void writePerNodeToDisk() {
try (FileOutputStream fos = new FileOutputStream(perNodePath)){ try (FileOutputStream fos = new FileOutputStream(perNodePath)) {
objectMapper.writeValue(fos, gossipCore.getPerNodeData()); objectMapper.writeValue(fos, gossipCore.getPerNodeData());
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn(e); log.error("Error!", e);
} }
} }
void writeSharedToDisk(){ void writeSharedToDisk() {
try (FileOutputStream fos = new FileOutputStream(sharedPath)){ try (FileOutputStream fos = new FileOutputStream(sharedPath)) {
objectMapper.writeValue(fos, gossipCore.getSharedData()); objectMapper.writeValue(fos, gossipCore.getSharedData());
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn(e); log.error("Error!", e);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ConcurrentHashMap<String, SharedDataMessage> readSharedDataFromDisk(){ ConcurrentHashMap<String, SharedDataMessage> readSharedDataFromDisk() {
if (!sharedPath.exists()) { if (!sharedPath.exists()) {
return new ConcurrentHashMap<>(); return new ConcurrentHashMap<>();
} }
try (FileInputStream fos = new FileInputStream(sharedPath)){ try (FileInputStream fos = new FileInputStream(sharedPath)) {
return objectMapper.readValue(fos, ConcurrentHashMap.class); return objectMapper.readValue(fos, ConcurrentHashMap.class);
} catch (IOException e) { } catch (IOException e) {
LOGGER.debug(e); log.error("Error!", e);
} }
return new ConcurrentHashMap<String, SharedDataMessage>(); return new ConcurrentHashMap<>();
} }
/** /** Writes all pernode and shared data to disk */
* Writes all pernode and shared data to disk
*/
@Override @Override
public void run() { public void run() {
writePerNodeToDisk(); writePerNodeToDisk();

View File

@ -17,6 +17,11 @@
*/ */
package org.apache.gossip.manager.handlers; package org.apache.gossip.manager.handlers;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.Member; import org.apache.gossip.Member;
import org.apache.gossip.RemoteMember; import org.apache.gossip.RemoteMember;
import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipCore;
@ -26,11 +31,7 @@ import org.apache.gossip.udp.UdpActiveGossipMessage;
import org.apache.gossip.udp.UdpActiveGossipOk; import org.apache.gossip.udp.UdpActiveGossipOk;
import org.apache.gossip.udp.UdpNotAMemberFault; import org.apache.gossip.udp.UdpNotAMemberFault;
import java.net.URI; @Slf4j
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
public class ActiveGossipMessageHandler implements MessageHandler { public class ActiveGossipMessageHandler implements MessageHandler {
/** /**
@ -49,7 +50,7 @@ public class ActiveGossipMessageHandler implements MessageHandler {
try { try {
u = new URI(activeGossipMessage.getMembers().get(i).getUri()); u = new URI(activeGossipMessage.getMembers().get(i).getUri());
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
GossipCore.LOGGER.debug("Gossip message with faulty URI", e); log.debug("Gossip message with faulty URI", e);
continue; continue;
} }
RemoteMember member = new RemoteMember( RemoteMember member = new RemoteMember(
@ -66,7 +67,7 @@ public class ActiveGossipMessageHandler implements MessageHandler {
f.setException("Not a member of this cluster " + i); f.setException("Not a member of this cluster " + i);
f.setUriFrom(activeGossipMessage.getUriFrom()); f.setUriFrom(activeGossipMessage.getUriFrom());
f.setUuid(activeGossipMessage.getUuid()); f.setUuid(activeGossipMessage.getUuid());
GossipCore.LOGGER.warn(f); log.warn("Warn", f);
gossipCore.sendOneWay(f, member.getUri()); gossipCore.sendOneWay(f, member.getUri());
continue; continue;
} }

View File

@ -29,4 +29,4 @@ public interface MessageHandler {
* @return boolean indicating success. * @return boolean indicating success.
*/ */
boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base); boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base);
} }

View File

@ -18,40 +18,35 @@
package org.apache.gossip.manager.handlers; package org.apache.gossip.manager.handlers;
import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Stream;
import org.apache.gossip.model.*;
public class MessageHandlerFactory { public class MessageHandlerFactory {
public static MessageHandler defaultHandler() { public static MessageHandler defaultHandler() {
return concurrentHandler( return concurrentHandler(
new TypedMessageHandler(Response.class, new ResponseHandler()), new TypedMessageHandlerWrapper(Response.class, new ResponseHandler()),
new TypedMessageHandler(ShutdownMessage.class, new ShutdownMessageHandler()), new TypedMessageHandlerWrapper(ShutdownMessage.class, new ShutdownMessageHandler()),
new TypedMessageHandler(PerNodeDataMessage.class, new PerNodeDataMessageHandler()), new TypedMessageHandlerWrapper(PerNodeDataMessage.class, new PerNodeDataMessageHandler()),
new TypedMessageHandler(SharedDataMessage.class, new SharedDataMessageHandler()), new TypedMessageHandlerWrapper(SharedDataMessage.class, new SharedDataMessageHandler()),
new TypedMessageHandler(ActiveGossipMessage.class, new ActiveGossipMessageHandler()), new TypedMessageHandlerWrapper(ActiveGossipMessage.class, new ActiveGossipMessageHandler()),
new TypedMessageHandler(PerNodeDataBulkMessage.class, new PerNodeDataBulkMessageHandler()), new TypedMessageHandlerWrapper(
new TypedMessageHandler(SharedDataBulkMessage.class, new SharedDataBulkMessageHandler()) PerNodeDataBulkMessage.class, new PerNodeDataBulkMessageHandler()),
); new TypedMessageHandlerWrapper(
SharedDataBulkMessage.class, new SharedDataBulkMessageHandler()));
} }
public static MessageHandler concurrentHandler(MessageHandler... handlers) { public static MessageHandler concurrentHandler(MessageHandler... handlers) {
if (handlers == null) if (handlers == null) throw new NullPointerException("handlers cannot be null");
throw new NullPointerException("handlers cannot be null"); if (Arrays.stream(handlers).filter(Objects::nonNull).count() != handlers.length) {
if (Arrays.asList(handlers).stream().filter(i -> i != null).count() != handlers.length) {
throw new NullPointerException("found at least one null handler"); throw new NullPointerException("found at least one null handler");
} }
return new MessageHandler() { return (gossipCore, gossipManager, base) -> {
@Override public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, // return true if at least one of the component handlers return true.
Base base) { return Stream.of(handlers).filter((mi) -> mi.invoke(gossipCore, gossipManager, base)).count()
// return true if at least one of the component handlers return true. > 0;
return Arrays.asList(handlers).stream()
.filter((mi) -> mi.invoke(gossipCore, gossipManager, base)).count() > 0;
}
}; };
} }
} }

View File

@ -24,7 +24,7 @@ import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.udp.UdpPerNodeDataBulkMessage; import org.apache.gossip.udp.UdpPerNodeDataBulkMessage;
public class PerNodeDataBulkMessageHandler implements MessageHandler { public class PerNodeDataBulkMessageHandler implements MessageHandler {
/** /**
* @param gossipCore context. * @param gossipCore context.
* @param gossipManager context. * @param gossipManager context.
@ -34,8 +34,7 @@ public class PerNodeDataBulkMessageHandler implements MessageHandler {
@Override @Override
public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) {
UdpPerNodeDataBulkMessage udpMessage = (UdpPerNodeDataBulkMessage) base; UdpPerNodeDataBulkMessage udpMessage = (UdpPerNodeDataBulkMessage) base;
for (PerNodeDataMessage dataMsg: udpMessage.getMessages()) for (PerNodeDataMessage dataMsg : udpMessage.getMessages()) gossipCore.addPerNodeData(dataMsg);
gossipCore.addPerNodeData(dataMsg);
return true; return true;
} }
} }

View File

@ -23,7 +23,7 @@ import org.apache.gossip.model.Base;
import org.apache.gossip.udp.Trackable; import org.apache.gossip.udp.Trackable;
public class ResponseHandler implements MessageHandler { public class ResponseHandler implements MessageHandler {
/** /**
* @param gossipCore context. * @param gossipCore context.
* @param gossipManager context. * @param gossipManager context.

View File

@ -23,8 +23,8 @@ import org.apache.gossip.model.Base;
import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.udp.UdpSharedDataBulkMessage; import org.apache.gossip.udp.UdpSharedDataBulkMessage;
public class SharedDataBulkMessageHandler implements MessageHandler{ public class SharedDataBulkMessageHandler implements MessageHandler {
/** /**
* @param gossipCore context. * @param gossipCore context.
* @param gossipManager context. * @param gossipManager context.
@ -34,8 +34,7 @@ public class SharedDataBulkMessageHandler implements MessageHandler{
@Override @Override
public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) {
UdpSharedDataBulkMessage udpMessage = (UdpSharedDataBulkMessage) base; UdpSharedDataBulkMessage udpMessage = (UdpSharedDataBulkMessage) base;
for (SharedDataMessage dataMsg: udpMessage.getMessages()) for (SharedDataMessage dataMsg : udpMessage.getMessages()) gossipCore.addSharedData(dataMsg);
gossipCore.addSharedData(dataMsg);
return true; return true;
} }
} }

View File

@ -22,8 +22,8 @@ import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
import org.apache.gossip.udp.UdpSharedDataMessage; import org.apache.gossip.udp.UdpSharedDataMessage;
public class SharedDataMessageHandler implements MessageHandler{ public class SharedDataMessageHandler implements MessageHandler {
/** /**
* @param gossipCore context. * @param gossipCore context.
* @param gossipManager context. * @param gossipManager context.

View File

@ -24,7 +24,7 @@ import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.model.ShutdownMessage;
public class ShutdownMessageHandler implements MessageHandler { public class ShutdownMessageHandler implements MessageHandler {
/** /**
* @param gossipCore context. * @param gossipCore context.
* @param gossipManager context. * @param gossipManager context.

View File

@ -21,11 +21,11 @@ import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
public class TypedMessageHandler implements MessageHandler { public class TypedMessageHandlerWrapper implements MessageHandler {
final private Class<?> messageClass; private final Class<?> messageClass;
final private MessageHandler messageHandler; private final MessageHandler messageHandler;
public TypedMessageHandler(Class<?> messageClass, MessageHandler messageHandler) { public TypedMessageHandlerWrapper(Class<?> messageClass, MessageHandler messageHandler) {
if (messageClass == null || messageHandler == null) { if (messageClass == null || messageHandler == null) {
throw new NullPointerException(); throw new NullPointerException();
} }

View File

@ -23,10 +23,8 @@ import java.util.List;
public class ActiveGossipMessage extends Base { public class ActiveGossipMessage extends Base {
private List<Member> members = new ArrayList<>(); private List<Member> members = new ArrayList<>();
public ActiveGossipMessage(){ public ActiveGossipMessage() {}
}
public List<Member> getMembers() { public List<Member> getMembers() {
return members; return members;
@ -35,5 +33,4 @@ public class ActiveGossipMessage extends Base {
public void setMembers(List<Member> members) { public void setMembers(List<Member> members) {
this.members = members; this.members = members;
} }
} }

View File

@ -17,6 +17,4 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
public class ActiveGossipOk extends Response { public class ActiveGossipOk extends Response {}
}

View File

@ -17,16 +17,14 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
import org.apache.gossip.udp.UdpActiveGossipMessage;
import org.apache.gossip.udp.UdpActiveGossipOk;
import org.apache.gossip.udp.UdpPerNodeDataBulkMessage;
import org.apache.gossip.udp.UdpNotAMemberFault;
import org.apache.gossip.udp.UdpSharedDataBulkMessage;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.apache.gossip.udp.UdpActiveGossipMessage;
import org.apache.gossip.udp.UdpActiveGossipOk;
import org.apache.gossip.udp.UdpNotAMemberFault;
import org.apache.gossip.udp.UdpPerNodeDataBulkMessage;
import org.apache.gossip.udp.UdpSharedDataBulkMessage;
@JsonTypeInfo( @JsonTypeInfo(
use = JsonTypeInfo.Id.CLASS, use = JsonTypeInfo.Id.CLASS,

View File

@ -21,7 +21,7 @@ public abstract class Fault extends Response {
private String exception; private String exception;
public Fault(){} public Fault() {}
public String getException() { public String getException() {
return exception; return exception;
@ -35,6 +35,4 @@ public abstract class Fault extends Response {
public String toString() { public String toString() {
return "Fault [exception=" + exception + "]"; return "Fault [exception=" + exception + "]";
} }
} }

View File

@ -25,13 +25,11 @@ public class Member {
private String uri; private String uri;
private String id; private String id;
private Long heartbeat; private Long heartbeat;
private Map<String,String> properties; private Map<String, String> properties;
public Member(){ public Member() {}
} public Member(String cluster, String uri, String id, Long heartbeat) {
public Member(String cluster, String uri, String id, Long heartbeat){
this.cluster = cluster; this.cluster = cluster;
this.uri = uri; this.uri = uri;
this.id = id; this.id = id;
@ -80,8 +78,16 @@ public class Member {
@Override @Override
public String toString() { public String toString() {
return "Member [cluster=" + cluster + ", uri=" + uri + ", id=" + id + ", heartbeat=" return "Member [cluster="
+ heartbeat + ", properties=" + properties + "]"; + cluster
+ ", uri="
+ uri
+ ", id="
+ id
+ ", heartbeat="
+ heartbeat
+ ", properties="
+ properties
+ "]";
} }
} }

View File

@ -17,6 +17,4 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
public class Message extends Base { public class Message extends Base {}
}

View File

@ -19,11 +19,9 @@ package org.apache.gossip.model;
public class NotAMemberFault extends Fault { public class NotAMemberFault extends Fault {
public NotAMemberFault(){ public NotAMemberFault() {}
} public NotAMemberFault(String message) {
public NotAMemberFault(String message){
this.setException(message); this.setException(message);
} }
} }

View File

@ -32,8 +32,10 @@ public class PerNodeDataBulkMessage extends Base {
return messages; return messages;
} }
@Override public String toString() { @Override
return "GossipDataBulkMessage[" + messages.stream().map(Object::toString) public String toString() {
.collect(Collectors.joining(",")) + "]"; return "GossipDataBulkMessage["
+ messages.stream().map(Object::toString).collect(Collectors.joining(","))
+ "]";
} }
} }

View File

@ -31,30 +31,39 @@ public class PerNodeDataMessage extends Base {
public String getNodeId() { public String getNodeId() {
return nodeId; return nodeId;
} }
public void setNodeId(String nodeId) { public void setNodeId(String nodeId) {
this.nodeId = nodeId; this.nodeId = nodeId;
} }
public String getKey() { public String getKey() {
return key; return key;
} }
public void setKey(String key) { public void setKey(String key) {
this.key = key; this.key = key;
} }
public Object getPayload() { public Object getPayload() {
return payload; return payload;
} }
public void setPayload(Object payload) { public void setPayload(Object payload) {
this.payload = payload; this.payload = payload;
} }
public Long getTimestamp() { public Long getTimestamp() {
return timestamp; return timestamp;
} }
public void setTimestamp(Long timestamp) { public void setTimestamp(Long timestamp) {
this.timestamp = timestamp; this.timestamp = timestamp;
} }
public Long getExpireAt() { public Long getExpireAt() {
return expireAt; return expireAt;
} }
public void setExpireAt(Long expireAt) { public void setExpireAt(Long expireAt) {
this.expireAt = expireAt; this.expireAt = expireAt;
} }
@ -69,11 +78,18 @@ public class PerNodeDataMessage extends Base {
@Override @Override
public String toString() { public String toString() {
return "GossipDataMessage [nodeId=" + nodeId + ", key=" + key + ", payload=" + payload return "GossipDataMessage [nodeId="
+ ", timestamp=" + timestamp + ", expireAt=" + expireAt + nodeId
+ ", replicable=" + replicable + "]"; + ", key="
+ key
+ ", payload="
+ payload
+ ", timestamp="
+ timestamp
+ ", expireAt="
+ expireAt
+ ", replicable="
+ replicable
+ "]";
} }
} }

View File

@ -17,6 +17,4 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
public abstract class Response extends Base { public abstract class Response extends Base {}
}

View File

@ -32,8 +32,10 @@ public class SharedDataBulkMessage extends Base {
return messages; return messages;
} }
@Override public String toString() { @Override
return "SharedGossipDataBulkMessage[" + messages.stream().map(Object::toString) public String toString() {
.collect(Collectors.joining(",")) + "]"; return "SharedGossipDataBulkMessage["
+ messages.stream().map(Object::toString).collect(Collectors.joining(","))
+ "]";
} }
} }

View File

@ -17,7 +17,6 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
import org.apache.gossip.replication.AllReplicable;
import org.apache.gossip.replication.Replicable; import org.apache.gossip.replication.Replicable;
public class SharedDataMessage extends Base { public class SharedDataMessage extends Base {

View File

@ -22,10 +22,8 @@ public class ShutdownMessage extends Message {
public static final String PER_NODE_KEY = "gossipcore.shutdowmessage"; public static final String PER_NODE_KEY = "gossipcore.shutdowmessage";
private long shutdownAtNanos; private long shutdownAtNanos;
private String nodeId; private String nodeId;
public ShutdownMessage(){ public ShutdownMessage() {}
}
public String getNodeId() { public String getNodeId() {
return nodeId; return nodeId;
@ -47,5 +45,4 @@ public class ShutdownMessage extends Message {
public String toString() { public String toString() {
return "ShutdownMessage [shutdownAtNanos=" + shutdownAtNanos + ", nodeId=" + nodeId + "]"; return "ShutdownMessage [shutdownAtNanos=" + shutdownAtNanos + ", nodeId=" + nodeId + "]";
} }
} }

View File

@ -17,20 +17,23 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
public class SignedPayload extends Base{ public class SignedPayload extends Base {
private byte [] data; private byte[] data;
private byte [] signature; private byte[] signature;
public byte[] getData() { public byte[] getData() {
return data; return data;
} }
public void setData(byte[] data) { public void setData(byte[] data) {
this.data = data; this.data = data;
} }
public byte[] getSignature() { public byte[] getSignature() {
return signature; return signature;
} }
public void setSignature(byte[] signature) { public void setSignature(byte[] signature) {
this.signature = signature; this.signature = signature;
} }
} }

View File

@ -17,9 +17,8 @@
*/ */
package org.apache.gossip.protocol; package org.apache.gossip.protocol;
import org.apache.gossip.model.Base;
import java.io.IOException; import java.io.IOException;
import org.apache.gossip.model.Base;
/** interface for managing message marshaling. */ /** interface for managing message marshaling. */
public interface ProtocolManager { public interface ProtocolManager {

View File

@ -28,7 +28,7 @@ import org.apache.gossip.model.Base;
* @see Replicable * @see Replicable
*/ */
public class AllReplicable<T extends Base> implements Replicable<T> { public class AllReplicable<T extends Base> implements Replicable<T> {
@Override @Override
public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) { public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) {
return true; return true;

View File

@ -30,9 +30,9 @@ import java.util.List;
* @see Replicable * @see Replicable
*/ */
public class BlackListReplicable<T extends Base> implements Replicable<T> { public class BlackListReplicable<T extends Base> implements Replicable<T> {
private final List<LocalMember> blackListMembers; private final List<LocalMember> blackListMembers;
public BlackListReplicable(List<LocalMember> blackListMembers) { public BlackListReplicable(List<LocalMember> blackListMembers) {
if (blackListMembers == null) { if (blackListMembers == null) {
this.blackListMembers = new ArrayList<>(); this.blackListMembers = new ArrayList<>();

View File

@ -28,19 +28,21 @@ import org.apache.gossip.model.Base;
* @see Replicable * @see Replicable
*/ */
public class DataCenterReplicable<T extends Base> implements Replicable<T> { public class DataCenterReplicable<T extends Base> implements Replicable<T> {
@Override @Override
public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) { public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) {
if (!me.getProperties().containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) { if (!me.getProperties().containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) {
// replicate to others if I am not belong to any data center // replicate to others if I am not belong to any data center
return true; return true;
} else if (!destination.getProperties() } else if (!destination
.containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) { .getProperties()
.containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) {
// Do not replicate if the destination data center is not defined // Do not replicate if the destination data center is not defined
return false; return false;
} else { } else {
return me.getProperties().get(DatacenterRackAwareActiveGossiper.DATACENTER) return me.getProperties()
.equals(destination.getProperties().get(DatacenterRackAwareActiveGossiper.DATACENTER)); .get(DatacenterRackAwareActiveGossiper.DATACENTER)
.equals(destination.getProperties().get(DatacenterRackAwareActiveGossiper.DATACENTER));
} }
} }
} }

View File

@ -27,7 +27,7 @@ import org.apache.gossip.model.Base;
* @see Replicable * @see Replicable
*/ */
public class NotReplicable<T extends Base> implements Replicable<T> { public class NotReplicable<T extends Base> implements Replicable<T> {
@Override @Override
public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) { public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) {
return false; return false;

View File

@ -21,14 +21,15 @@ import org.apache.gossip.LocalMember;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
/** /**
* This interface is used to determine whether a data item needs to be replicated to * This interface is used to determine whether a data item needs to be replicated to another gossip
* another gossip member. * member.
* *
* @param <T> A subtype of the class {@link org.apache.gossip.model.Base} which uses this interface * @param <T> A subtype of the class {@link org.apache.gossip.model.Base} which uses this interface
*/ */
public interface Replicable<T extends Base> { public interface Replicable<T extends Base> {
/** /**
* Test for a given data item needs to be replicated. * Test for a given data item needs to be replicated.
*
* @param me node that the data item is going to transmit from. * @param me node that the data item is going to transmit from.
* @param destination target node to replicate. * @param destination target node to replicate.
* @param message this parameter is currently ignored * @param message this parameter is currently ignored

View File

@ -17,11 +17,10 @@
*/ */
package org.apache.gossip.replication; package org.apache.gossip.replication;
import org.apache.gossip.LocalMember;
import org.apache.gossip.model.Base;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.gossip.LocalMember;
import org.apache.gossip.model.Base;
/** /**
* Replicable implementation which replicates data to given set of nodes. * Replicable implementation which replicates data to given set of nodes.

View File

@ -30,8 +30,8 @@ import java.security.SecureRandom;
public class KeyTool { public class KeyTool {
public static void generatePubandPrivateKeyFiles(String path, String id) public static void generatePubandPrivateKeyFiles(String path, String id)
throws NoSuchAlgorithmException, NoSuchProviderException, IOException{ throws NoSuchAlgorithmException, NoSuchProviderException, IOException {
SecureRandom r = new SecureRandom(); SecureRandom r = new SecureRandom();
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN"); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
keyGen.initialize(1024, r); keyGen.initialize(1024, r);
@ -49,9 +49,9 @@ public class KeyTool {
sigfos.close(); sigfos.close();
} }
} }
public static void main (String [] args) throws public static void main(String[] args)
NoSuchAlgorithmException, NoSuchProviderException, IOException{ throws NoSuchAlgorithmException, NoSuchProviderException, IOException {
generatePubandPrivateKeyFiles(args[0], args[1]); generatePubandPrivateKeyFiles(args[0], args[1]);
} }
} }

View File

@ -18,27 +18,25 @@
package org.apache.gossip.transport; package org.apache.gossip.transport;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.gossip.manager.AbstractActiveGossiper; import org.apache.gossip.manager.AbstractActiveGossiper;
import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.utils.ReflectionUtils; import org.apache.gossip.utils.ReflectionUtils;
import org.apache.log4j.Logger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/** /**
* Manage the protcol threads (active and passive gossipers). * Manage the protcol threads (active and passive gossipers).
*/ */
@Slf4j
public abstract class AbstractTransportManager implements TransportManager { public abstract class AbstractTransportManager implements TransportManager {
public static final Logger LOGGER = Logger.getLogger(AbstractTransportManager.class);
private final ExecutorService gossipThreadExecutor;
private final AbstractActiveGossiper activeGossipThread;
protected final GossipManager gossipManager; protected final GossipManager gossipManager;
protected final GossipCore gossipCore; protected final GossipCore gossipCore;
private final ExecutorService gossipThreadExecutor;
private final AbstractActiveGossiper activeGossipThread;
public AbstractTransportManager(GossipManager gossipManager, GossipCore gossipCore) { public AbstractTransportManager(GossipManager gossipManager, GossipCore gossipCore) {
this.gossipManager = gossipManager; this.gossipManager = gossipManager;
@ -65,10 +63,10 @@ public abstract class AbstractTransportManager implements TransportManager {
boolean result = gossipThreadExecutor.awaitTermination(10, TimeUnit.MILLISECONDS); boolean result = gossipThreadExecutor.awaitTermination(10, TimeUnit.MILLISECONDS);
if (!result) { if (!result) {
// common when blocking patterns are used to read data from a socket. // common when blocking patterns are used to read data from a socket.
LOGGER.warn("executor shutdown timed out"); log.warn("executor shutdown timed out");
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.error(e); log.error("Error!", e);
} }
gossipThreadExecutor.shutdownNow(); gossipThreadExecutor.shutdownNow();
} }

View File

@ -22,19 +22,25 @@ import java.net.URI;
/** interface for manager that sends and receives messages that have already been serialized. */ /** interface for manager that sends and receives messages that have already been serialized. */
public interface TransportManager { public interface TransportManager {
/** starts the active gossip thread responsible for reaching out to remote nodes. Not related to `startEndpoint()` */ /**
* starts the active gossip thread responsible for reaching out to remote nodes. Not related to
* `startEndpoint()`
*/
void startActiveGossiper(); void startActiveGossiper();
/** starts the passive gossip thread that receives messages from remote nodes. Not related to `startActiveGossiper()` */ /**
* starts the passive gossip thread that receives messages from remote nodes. Not related to
* `startActiveGossiper()`
*/
void startEndpoint(); void startEndpoint();
/** attempts to shutdown all threads. */ /** attempts to shutdown all threads. */
void shutdown(); void shutdown();
/** sends a payload to an endpoint. */ /** sends a payload to an endpoint. */
void send(URI endpoint, byte[] buf) throws IOException; void send(URI endpoint, byte[] buf) throws IOException;
/** gets the next payload being sent to this node */ /** gets the next payload being sent to this node */
byte[] read() throws IOException; byte[] read() throws IOException;
} }

View File

@ -20,11 +20,10 @@ package org.apache.gossip.udp;
public interface Trackable { public interface Trackable {
String getUriFrom(); String getUriFrom();
void setUriFrom(String uriFrom); void setUriFrom(String uriFrom);
String getUuid(); String getUuid();
void setUuid(String uuid); void setUuid(String uuid);
} }

View File

@ -23,27 +23,31 @@ public class UdpActiveGossipMessage extends ActiveGossipMessage implements Track
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
@Override @Override
public String toString() { public String toString() {
return "UdpActiveGossipMessage [uriFrom=" + uriFrom + ", uuid=" + uuid + ", getMembers()=" return "UdpActiveGossipMessage [uriFrom="
+ getMembers() + "]"; + uriFrom
+ ", uuid="
+ uuid
+ ", getMembers()="
+ getMembers()
+ "]";
} }
} }

View File

@ -21,24 +21,22 @@ import org.apache.gossip.model.ActiveGossipOk;
public class UdpActiveGossipOk extends ActiveGossipOk implements Trackable { public class UdpActiveGossipOk extends ActiveGossipOk implements Trackable {
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
} }

View File

@ -19,28 +19,25 @@ package org.apache.gossip.udp;
import org.apache.gossip.model.NotAMemberFault; import org.apache.gossip.model.NotAMemberFault;
public class UdpNotAMemberFault extends NotAMemberFault implements Trackable{ public class UdpNotAMemberFault extends NotAMemberFault implements Trackable {
public UdpNotAMemberFault(){
}
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public UdpNotAMemberFault() {}
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
} }

View File

@ -23,27 +23,31 @@ public class UdpPerNodeDataBulkMessage extends PerNodeDataBulkMessage implements
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
@Override @Override
public String toString() { public String toString() {
return "UdpGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid return "UdpGossipDataMessage [uriFrom="
+ ", messages=[" + super.toString() + "] ]"; + uriFrom
+ ", uuid="
+ uuid
+ ", messages=["
+ super.toString()
+ "] ]";
} }
} }

View File

@ -23,27 +23,31 @@ public class UdpPerNodeDataMessage extends PerNodeDataMessage implements Trackab
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
@Override @Override
public String toString() { public String toString() {
return "UdpGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid return "UdpGossipDataMessage [uriFrom="
+ ", getReplicable()=" + getReplicable() + "]"; + uriFrom
+ ", uuid="
+ uuid
+ ", getReplicable()="
+ getReplicable()
+ "]";
} }
} }

View File

@ -23,27 +23,32 @@ public class UdpSharedDataBulkMessage extends SharedDataBulkMessage implements T
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
@Override @Override
public String toString() { public String toString() {
return "UdpSharedGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid + ", getNodeId()=" return "UdpSharedGossipDataMessage [uriFrom="
+ ", messages=[" + super.toString() + "] ]"; + uriFrom
+ ", uuid="
+ uuid
+ ", getNodeId()="
+ ", messages=["
+ super.toString()
+ "] ]";
} }
} }

View File

@ -23,29 +23,41 @@ public class UdpSharedDataMessage extends SharedDataMessage implements Trackable
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;
public String getUriFrom() { public String getUriFrom() {
return uriFrom; return uriFrom;
} }
public void setUriFrom(String uriFrom) { public void setUriFrom(String uriFrom) {
this.uriFrom = uriFrom; this.uriFrom = uriFrom;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
@Override @Override
public String toString() { public String toString() {
return "UdpSharedGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid + ", getNodeId()=" return "UdpSharedGossipDataMessage [uriFrom="
+ getNodeId() + ", getKey()=" + getKey() + ", getPayload()=" + getPayload() + uriFrom
+ ", getTimestamp()=" + getTimestamp() + ", getExpireAt()=" + getExpireAt() + ", uuid="
+ ", getReplicable()=" + getReplicable() + "]"; + uuid
+ ", getNodeId()="
+ getNodeId()
+ ", getKey()="
+ getKey()
+ ", getPayload()="
+ getPayload()
+ ", getTimestamp()="
+ getTimestamp()
+ ", getExpireAt()="
+ getExpireAt()
+ ", getReplicable()="
+ getReplicable()
+ "]";
} }
} }

View File

@ -23,8 +23,9 @@ import java.lang.reflect.InvocationTargetException;
public class ReflectionUtils { public class ReflectionUtils {
/** /**
* Create an instance of a thing. This method essentially makes code more readable by handing the various exception * Create an instance of a thing. This method essentially makes code more readable by handing the
* trapping. * various exception trapping.
*
* @param className * @param className
* @param constructorTypes * @param constructorTypes
* @param constructorArgs * @param constructorArgs
@ -32,20 +33,23 @@ public class ReflectionUtils {
* @return constructed instance of a thing. * @return constructed instance of a thing.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T constructWithReflection(String className, Class<?>[] constructorTypes, Object[] constructorArgs) { public static <T> T constructWithReflection(
String className, Class<?>[] constructorTypes, Object[] constructorArgs) {
try { try {
Constructor<?> c = Class.forName(className).getConstructor(constructorTypes); Constructor<?> c = Class.forName(className).getConstructor(constructorTypes);
c.setAccessible(true); c.setAccessible(true);
return (T) c.newInstance(constructorArgs); return (T) c.newInstance(constructorArgs);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
// catch ITE and throw the target if it is a RTE. // catch ITE and throw the target if it is a RTE.
if (e.getTargetException() != null && RuntimeException.class.isAssignableFrom(e.getTargetException().getClass())) { if (e.getTargetException() != null
&& RuntimeException.class.isAssignableFrom(e.getTargetException().getClass())) {
throw (RuntimeException) e.getTargetException(); throw (RuntimeException) e.getTargetException();
} else { } else {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} catch (ReflectiveOperationException others) { } catch (ReflectiveOperationException others) {
// Note: No class in the above list should be a descendent of RuntimeException. Otherwise, we're just wrapping // Note: No class in the above list should be a descendent of RuntimeException. Otherwise,
// we're just wrapping
// and making stack traces confusing. // and making stack traces confusing.
throw new RuntimeException(others); throw new RuntimeException(others);
} }

View File

@ -9,12 +9,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
log4j.rootLogger=INFO,stdout log4j.rootLogger=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
log4j.logger.io.teknek=DEBUG log4j.logger.io.teknek=DEBUG
log4j.logger.com.google.code.gossip=INFO log4j.logger.com.google.code.gossip=INFO

View File

@ -31,14 +31,14 @@ import org.junit.Before;
public abstract class AbstractIntegrationBase { public abstract class AbstractIntegrationBase {
List <GossipManager> nodes = new ArrayList<>(); List<GossipManager> nodes = new ArrayList<>();
public void register(GossipManager manager){ public void register(GossipManager manager) {
nodes.add(manager); nodes.add(manager);
} }
public void generateStandardNodes(final int memberCount) throws URISyntaxException { public void generateStandardNodes(final int memberCount) throws URISyntaxException {
if(nodes.size() > 0){ if (nodes.size() > 0) {
after(); after();
nodes.clear(); nodes.clear();
} }
@ -55,24 +55,30 @@ public abstract class AbstractIntegrationBase {
for (int i = 1; i < memberCount + 1; ++i) { for (int i = 1; i < memberCount + 1; ++i) {
URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster(cluster).uri(uri) GossipManager gossipService =
.id(i + "").gossipMembers(startupMembers).gossipSettings(settings).build(); GossipManagerBuilder.newBuilder()
.cluster(cluster)
.uri(uri)
.id(i + "")
.gossipMembers(startupMembers)
.gossipSettings(settings)
.build();
gossipService.init(); gossipService.init();
register(gossipService); register(gossipService);
} }
} }
@Before @Before
public void before(){ public void before() {
nodes = new ArrayList<>(); nodes = new ArrayList<>();
} }
@After @After
public void after(){ public void after() {
for (GossipManager node: nodes){ for (GossipManager node : nodes) {
if (node !=null){ if (node != null) {
node.shutdown(); node.shutdown();
} }
} }
} }
} }

View File

@ -20,21 +20,31 @@ package org.apache.gossip;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.HashMap; import java.util.HashMap;
import org.junit.jupiter.api.Assertions;
import org.junit.Assert;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
@RunWith(JUnitPlatform.class)
public class MemberTest { public class MemberTest {
@Test @Test
public void testHashCodeFromGossip40() throws URISyntaxException { public void testHashCodeFromGossip40() throws URISyntaxException {
Assert.assertNotEquals( Assertions.assertNotEquals(new LocalMember(
new LocalMember("mycluster", new URI("udp://4.4.4.4:1000"), "myid", 1, new HashMap<String,String>(), 10, 5, "exponential") "mycluster",
.hashCode(), new URI("udp://4.4.4.4:1000"),
new LocalMember("mycluster", new URI("udp://4.4.4.5:1005"), "yourid", 11, new HashMap<String,String>(), 11, 6, "exponential") "myid",
.hashCode()); 1,
new HashMap<>(),
10,
5,
"exponential")
.hashCode(), new LocalMember(
"mycluster",
new URI("udp://4.4.4.5:1005"),
"yourid",
11,
new HashMap<>(),
11,
6,
"exponential")
.hashCode());
} }
} }

View File

@ -17,24 +17,15 @@
*/ */
package org.apache.gossip.accrual; package org.apache.gossip.accrual;
import org.apache.gossip.GossipSettings;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import org.apache.gossip.GossipSettings;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@RunWith(JUnitPlatform.class)
public class FailureDetectorTest { public class FailureDetectorTest {
@FunctionalInterface
interface TriConsumer<A, B, C> {
void accept(A a, B b, C c);
}
static final Double failureThreshold = new GossipSettings().getConvictThreshold(); static final Double failureThreshold = new GossipSettings().getConvictThreshold();
List<Integer> generateTimeList(int begin, int end, int step) { List<Integer> generateTimeList(int begin, int end, int step) {
@ -52,8 +43,8 @@ public class FailureDetectorTest {
public void normalDistribution() { public void normalDistribution() {
FailureDetector fd = new FailureDetector(1, 1000, "normal"); FailureDetector fd = new FailureDetector(1, 1000, "normal");
List<Integer> values = generateTimeList(0, 10000, 100); List<Integer> values = generateTimeList(0, 10000, 100);
Double deltaSum = 0.0; double deltaSum = 0.0;
Integer deltaCount = 0; int deltaCount = 0;
for (int i = 0; i < values.size() - 1; i++) { for (int i = 0; i < values.size() - 1; i++) {
fd.recordHeartbeat(values.get(i)); fd.recordHeartbeat(values.get(i));
if (i != 0) { if (i != 0) {
@ -64,21 +55,23 @@ public class FailureDetectorTest {
Integer lastRecorded = values.get(values.size() - 2); Integer lastRecorded = values.get(values.size() - 2);
//after "step" delay we need to be considered UP //after "step" delay we need to be considered UP
Assert.assertTrue(fd.computePhiMeasure(values.get(values.size() - 1)) < failureThreshold); Assertions.assertTrue(fd.computePhiMeasure(values.get(values.size() - 1)) < failureThreshold);
//if we check phi-measure after mean delay we get value for 0.5 probability(normal distribution) //if we check phi-measure after mean delay we get value for 0.5 probability(normal distribution)
Assert.assertEquals(fd.computePhiMeasure(lastRecorded + Math.round(deltaSum / deltaCount)), -Math.log10(0.5), 0.1); Assertions.assertEquals(fd.computePhiMeasure(lastRecorded + Math.round(deltaSum / deltaCount)),
-Math.log10(0.5),
0.1);
} }
@Test @Test
public void checkMinimumSamples() { public void checkMinimumSamples() {
Integer minimumSamples = 5; int minimumSamples = 5;
FailureDetector fd = new FailureDetector(minimumSamples, 1000, "normal"); FailureDetector fd = new FailureDetector(minimumSamples, 1000, "normal");
for (int i = 0; i < minimumSamples + 1; i++) { // +1 because we don't place first heartbeat into structure for (int i = 0; i < minimumSamples + 1; i++) { // +1 because we don't place first heartbeat into structure
Assert.assertNull(fd.computePhiMeasure(100)); Assertions.assertNull(fd.computePhiMeasure(100));
fd.recordHeartbeat(i); fd.recordHeartbeat(i);
} }
Assert.assertNotNull(fd.computePhiMeasure(100)); Assertions.assertNotNull(fd.computePhiMeasure(100));
} }
@Test @Test
@ -86,28 +79,33 @@ public class FailureDetectorTest {
final FailureDetector fd = new FailureDetector(5, 1000, "normal"); final FailureDetector fd = new FailureDetector(5, 1000, "normal");
TriConsumer<Integer, Integer, Integer> checkAlive = (begin, end, step) -> { TriConsumer<Integer, Integer, Integer> checkAlive = (begin, end, step) -> {
List<Integer> times = generateTimeList(begin, end, step); List<Integer> times = generateTimeList(begin, end, step);
for (int i = 0; i < times.size(); i++) { for (Integer time : times) {
Double current = fd.computePhiMeasure(times.get(i)); Double current = fd.computePhiMeasure(time);
if (current != null) { if (current != null) {
Assert.assertTrue(current < failureThreshold); Assertions.assertTrue(current < failureThreshold);
}
fd.recordHeartbeat(time);
} }
fd.recordHeartbeat(times.get(i));
}
}; };
TriConsumer<Integer, Integer, Integer> checkDeadMonotonic = (begin, end, step) -> { TriConsumer<Integer, Integer, Integer> checkDeadMonotonic = (begin, end, step) -> {
List<Integer> times = generateTimeList(begin, end, step); List<Integer> times = generateTimeList(begin, end, step);
Double prev = null; Double prev = null;
for (int i = 0; i < times.size(); i++) { for (Integer time : times) {
Double current = fd.computePhiMeasure(times.get(i)); Double current = fd.computePhiMeasure(time);
if (current != null && prev != null) { if (current != null && prev != null) {
Assert.assertTrue(current >= prev); Assertions.assertTrue(current >= prev);
}
prev = current;
} }
prev = current;
}
}; };
checkAlive.accept(0, 20000, 100); checkAlive.accept(0, 20000, 100);
checkDeadMonotonic.accept(20000, 20500, 5); checkDeadMonotonic.accept(20000, 20500, 5);
} }
@FunctionalInterface
interface TriConsumer<A, B, C> {
void accept(A a, B b, C c);
}
} }

View File

@ -39,16 +39,17 @@ import java.util.stream.Stream;
*/ */
@Ignore @Ignore
public abstract class AddRemoveStringSetTest<SetType extends CrdtAddRemoveSet<String, Set<String>, SetType>> { public abstract class AddRemoveStringSetTest<
SetType extends CrdtAddRemoveSet<String, Set<String>, SetType>> {
private Set<String> sampleSet;
abstract SetType construct(Set<String> set); abstract SetType construct(Set<String> set);
abstract SetType construct(); abstract SetType construct();
private Set<String> sampleSet;
@Before @Before
public void setup(){ public void setup() {
sampleSet = new HashSet<>(); sampleSet = new HashSet<>();
sampleSet.add("4"); sampleSet.add("4");
sampleSet.add("5"); sampleSet.add("5");
@ -56,24 +57,25 @@ public abstract class AddRemoveStringSetTest<SetType extends CrdtAddRemoveSet<St
} }
@Test @Test
public void abstractSetConstructorTest(){ public void abstractSetConstructorTest() {
Assert.assertEquals(construct(sampleSet).value(), sampleSet); Assert.assertEquals(construct(sampleSet).value(), sampleSet);
} }
@Test @Test
public void abstractStressWithSetTest(){ public void abstractStressWithSetTest() {
Set<String> hashSet = new HashSet<>(); Set<String> hashSet = new HashSet<>();
SetType set = construct(); SetType set = construct();
for (int it = 0; it < 40; it++){ for (int it = 0; it < 40; it++) {
SetType newSet; SetType newSet;
if (it % 5 == 1){ if (it % 5 == 1) {
//deleting existing // deleting existing
String forDelete = hashSet.stream().skip((long) (hashSet.size() * Math.random())).findFirst().get(); String forDelete =
hashSet.stream().skip((long) (hashSet.size() * Math.random())).findFirst().get();
newSet = set.remove(forDelete); newSet = set.remove(forDelete);
Assert.assertEquals(set.value(), hashSet); // check old version is immutable Assert.assertEquals(set.value(), hashSet); // check old version is immutable
hashSet.remove(forDelete); hashSet.remove(forDelete);
} else { } else {
//adding // adding
String forAdd = String.valueOf((int) (10000 * Math.random())); String forAdd = String.valueOf((int) (10000 * Math.random()));
newSet = set.add(forAdd); newSet = set.add(forAdd);
Assert.assertEquals(set.value(), hashSet); // check old version is immutable Assert.assertEquals(set.value(), hashSet); // check old version is immutable
@ -85,7 +87,7 @@ public abstract class AddRemoveStringSetTest<SetType extends CrdtAddRemoveSet<St
} }
@Test @Test
public void abstractEqualsTest(){ public void abstractEqualsTest() {
SetType set = construct(sampleSet); SetType set = construct(sampleSet);
Assert.assertFalse(set.equals(sampleSet)); Assert.assertFalse(set.equals(sampleSet));
SetType newSet = set.add("25"); SetType newSet = set.add("25");
@ -95,7 +97,7 @@ public abstract class AddRemoveStringSetTest<SetType extends CrdtAddRemoveSet<St
} }
@Test @Test
public void abstractRemoveMissingTest(){ public void abstractRemoveMissingTest() {
SetType set = construct(sampleSet); SetType set = construct(sampleSet);
set = set.add("25"); set = set.add("25");
set = set.remove("25"); set = set.remove("25");
@ -107,15 +109,16 @@ public abstract class AddRemoveStringSetTest<SetType extends CrdtAddRemoveSet<St
} }
@Test @Test
public void abstractStressMergeTest(){ public void abstractStressMergeTest() {
// in one-process context, add, remove and merge operations of lww are equal to operations of Set // in one-process context, add, remove and merge operations of lww are equal to operations of
// Set
// we've already checked it. Now just check merge // we've already checked it. Now just check merge
Set<String> hashSet1 = new HashSet<>(), hashSet2 = new HashSet<>(); Set<String> hashSet1 = new HashSet<>(), hashSet2 = new HashSet<>();
SetType set1 = construct(), set2 = construct(); SetType set1 = construct(), set2 = construct();
for (int it = 0; it < 100; it++){ for (int it = 0; it < 100; it++) {
String forAdd = String.valueOf((int) (10000 * Math.random())); String forAdd = String.valueOf((int) (10000 * Math.random()));
if (it % 2 == 0){ if (it % 2 == 0) {
hashSet1.add(forAdd); hashSet1.add(forAdd);
set1 = set1.add(forAdd); set1 = set1.add(forAdd);
} else { } else {
@ -125,12 +128,13 @@ public abstract class AddRemoveStringSetTest<SetType extends CrdtAddRemoveSet<St
} }
Assert.assertEquals(set1.value(), hashSet1); Assert.assertEquals(set1.value(), hashSet1);
Assert.assertEquals(set2.value(), hashSet2); Assert.assertEquals(set2.value(), hashSet2);
Set<String> mergedSet = Stream.concat(hashSet1.stream(), hashSet2.stream()).collect(Collectors.toSet()); Set<String> mergedSet =
Stream.concat(hashSet1.stream(), hashSet2.stream()).collect(Collectors.toSet());
Assert.assertEquals(set1.merge(set2).value(), mergedSet); Assert.assertEquals(set1.merge(set2).value(), mergedSet);
} }
@Test @Test
public void abstractOptimizeTest(){ public void abstractOptimizeTest() {
Assert.assertEquals(construct(sampleSet).value(), sampleSet); Assert.assertEquals(construct(sampleSet).value(), sampleSet);
Assert.assertEquals(construct(sampleSet).optimize().value(), sampleSet); Assert.assertEquals(construct(sampleSet).optimize().value(), sampleSet);
} }

View File

@ -17,11 +17,10 @@
*/ */
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
public class GrowOnlyCounterTest { public class GrowOnlyCounterTest {

View File

@ -27,12 +27,13 @@ public class GrowOnlySetTest {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Test @Test
public void mergeTest(){ public void mergeTest() {
ConcurrentHashMap<String, Crdt> a = new ConcurrentHashMap<>(); ConcurrentHashMap<String, Crdt> a = new ConcurrentHashMap<>();
GrowOnlySet<String> gset = new GrowOnlySet<>(Arrays.asList("a", "b")); GrowOnlySet<String> gset = new GrowOnlySet<>(Arrays.asList("a", "b"));
Assert.assertEquals(gset, a.merge("a", gset, new CrdtBiFunctionMerge())); Assert.assertEquals(gset, a.merge("a", gset, new CrdtBiFunctionMerge()));
GrowOnlySet<String> over = new GrowOnlySet<>(Arrays.asList("b", "d")); GrowOnlySet<String> over = new GrowOnlySet<>(Arrays.asList("b", "d"));
Assert.assertEquals(new GrowOnlySet<>(Arrays.asList("a", "b", "d")), Assert.assertEquals(
a.merge("a", over, CrdtBiFunctionMerge::applyStatic)); new GrowOnlySet<>(Arrays.asList("a", "b", "d")),
a.merge("a", over, CrdtBiFunctionMerge::applyStatic));
} }
} }

View File

@ -28,18 +28,18 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
public class LwwSetTest extends AddRemoveStringSetTest<LwwSet<String>> { public class LwwSetTest extends AddRemoveStringSetTest<LwwSet<String>> {
static private Clock clock = new SystemClock(); private static Clock clock = new SystemClock();
LwwSet<String> construct(Set<String> set){ LwwSet<String> construct(Set<String> set) {
return new LwwSet<>(set); return new LwwSet<>(set);
} }
LwwSet<String> construct(){ LwwSet<String> construct() {
return new LwwSet<>(); return new LwwSet<>();
} }
@Test @Test
public void valueTest(){ public void valueTest() {
Map<Character, LwwSet.Timestamps> map = new HashMap<>(); Map<Character, LwwSet.Timestamps> map = new HashMap<>();
map.put('a', new LwwSet.Timestamps(1, 0)); map.put('a', new LwwSet.Timestamps(1, 0));
map.put('b', new LwwSet.Timestamps(1, 2)); map.put('b', new LwwSet.Timestamps(1, 2));
@ -52,14 +52,15 @@ public class LwwSetTest extends AddRemoveStringSetTest<LwwSet<String>> {
} }
@Test @Test
public void fakeTimeMergeTest(){ public void fakeTimeMergeTest() {
// try to create LWWSet with time from future (simulate other process with its own clock) and validate result // try to create LWWSet with time from future (simulate other process with its own clock) and
// validate result
// check remove from the future // check remove from the future
Map<Integer, LwwSet.Timestamps> map = new HashMap<>(); Map<Integer, LwwSet.Timestamps> map = new HashMap<>();
map.put(25, new LwwSet.Timestamps(clock.nanoTime(), Long.MAX_VALUE)); map.put(25, new LwwSet.Timestamps(clock.nanoTime(), Long.MAX_VALUE));
LwwSet<Integer> lww = new LwwSet<>(map); LwwSet<Integer> lww = new LwwSet<>(map);
Assert.assertEquals(lww, new LwwSet<Integer>()); Assert.assertEquals(lww, new LwwSet<Integer>());
//create new LWWSet with element 25, and merge with other LWW which has remove in future // create new LWWSet with element 25, and merge with other LWW which has remove in future
Assert.assertEquals(new LwwSet<>(25).merge(lww), new LwwSet<Integer>()); Assert.assertEquals(new LwwSet<>(25).merge(lww), new LwwSet<Integer>());
// add in future // add in future

View File

@ -17,13 +17,12 @@
*/ */
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
public class MaxChangeSetTest extends AddRemoveStringSetTest<MaxChangeSet<String>> { public class MaxChangeSetTest extends AddRemoveStringSetTest<MaxChangeSet<String>> {
MaxChangeSet<String> construct(Set<String> set){ MaxChangeSet<String> construct(Set<String> set){

View File

@ -17,13 +17,12 @@
*/ */
package org.apache.gossip.crdt; package org.apache.gossip.crdt;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import org.junit.Assert;
import org.junit.Test;
public class OrSetTest extends AddRemoveStringSetTest<OrSet<String>> { public class OrSetTest extends AddRemoveStringSetTest<OrSet<String>> {
OrSet<String> construct(){ OrSet<String> construct(){

Some files were not shown because too many files have changed in this diff Show More