-
Notifications
You must be signed in to change notification settings - Fork 290
Hazelcast impl #1011
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hazelcast impl #1011
Changes from all commits
8de14d7
1f2e850
6b34efe
51beeac
2c68b30
d30c665
daa728c
3cc4a55
5ac64ad
d041dbe
d9ff616
0cf1663
d18d860
d54d09f
04b1c27
2b44bfe
c1c8636
101ef62
debed20
498138a
c40e360
31c0159
6802a81
9b0d53b
c0569c5
2423e3a
8722400
1f53523
abab9df
323faea
f963e01
babf20e
751bea2
ccc1e43
ccef94e
6b4a37a
ae76e3b
c38cbe9
121a26d
cc9f1b5
471c06c
9d9d2e7
8d170cb
87b83e1
12b9bb2
80a272a
9c792d4
c69e3bd
2b24f01
a21ab4e
5e89289
49938e1
b130eda
70c66d1
f29e7c7
ee6157f
bb35c83
2f1f5c4
1c4a0fd
571c59c
40272b1
5b36888
6e3f041
b2b97e1
40f747a
6d7cd73
5d222f1
bdcc2d7
5fca872
f4bc46a
1d9a0d6
5e676a0
96f17bd
93ea925
37dffa4
4c7cf4e
1ef10ac
dc90b71
6762df9
42fbbbe
fcad4b5
c784cdb
53c9201
3a9f4fa
6c16a31
130e728
f4429bb
b2715e5
392da69
a7025ef
892f175
ffec861
5887ec3
6c7fba2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,3 +19,4 @@ hostkey.ser | |
| /eclipse-classes | ||
| .vscode/ | ||
| .factorypath | ||
| graphify-out | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # Distributed Event Management support | ||
|
|
||
| The plugin supports Distributed Event Management support where two or more replicas or nodes of a logical Jenkins(*) instance | ||
| run in parallel (sharing the Gerrit memory of the plugin). When enabled, a Hazelcast | ||
| cluster coordinates the instances so that: | ||
|
|
||
| - Each Gerrit event is processed by **exactly one** instance (event claiming) | ||
| - Build state is shared across instances (distributed build memory) | ||
| - Gerrit feedback (votes and comments) are sent **exactly once** per build event | ||
|
|
||
| By default, the plugin runs in **local mode** and requires no additional configuration. | ||
| Local mode is fully backward-compatible with single-instance Jenkins deployments. | ||
|
|
||
| Alternative coordination backends can be implemented by extending | ||
| [`CoordinationModeProvider`](../src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/spi/CoordinationModeProvider.java) | ||
| — a Jenkins `ExtensionPoint` that wires together the storage, event-claiming, and | ||
| notification-claiming strategies for a given coordination mode. A higher `@Extension` | ||
| ordinal takes precedence over the built-in Hazelcast provider. | ||
|
|
||
| ## Hazelcast implementation | ||
|
|
||
| Hazelcast mode is activated via a JVM system property. Jenkins connects as a lightweight | ||
| client to a Hazelcast sidecar container, reusing the cross-pod cluster the sidecar | ||
| maintains. | ||
|
|
||
| ### Configuration Properties | ||
|
|
||
| All distributed storage settings are controlled by JVM system properties passed to Jenkins on startup. | ||
|
|
||
| | Property | Default | Description | | ||
| |---|---|-------------------------------------------------------| | ||
| | `gerrit.trigger.coordination.mode` | `local` | Set to `hazelcast` to enable distributed coordination | | ||
| | `gerrit.trigger.coordination.hazelcast.client.addresses` | `localhost:5702` | Comma-separated `host:port` list of sidecar addresses | | ||
| | `gerrit.trigger.coordination.hazelcast.client.cluster.name` | `gerrit-trigger-cluster` | Cluster name to connect to | | ||
|
|
||
| Port `5702` is used by default to avoid potential conflicts with other Hazelcast cluster, which could occupy port `5701`. | ||
|
|
||
| Cluster name must be different for each logical instance. Multiple replicas or nodes of a logical instance may configure the same cluster name. Different logical instances require separate cluster names. | ||
|
|
||
| ### Configuration Example | ||
|
|
||
| #### Kubernetes — Client Mode with Hazelcast Sidecar | ||
|
|
||
| The plugin can connect to Hazelcast cluster as a lightweight client. For example, if we are running | ||
| K8s environment with the Jenkins instance inside a pod, we can have a side-container with Hazelcast | ||
| to set up the Hazelcast cluster. In this kind of cases, we would the a configuration setup similar | ||
| to the following one: | ||
|
|
||
| Add the following JVM arguments to the Jenkins instance: | ||
|
|
||
| -Dgerrit.trigger.coordination.mode=hazelcast | ||
| -Dgerrit.trigger.coordination.hazelcast.client.addresses=localhost:5702 | ||
| -Dgerrit.trigger.coordination.hazelcast.client.cluster.name=gerrit-trigger-cluster | ||
|
|
||
| Add the sidecar container to the instance pod spec: | ||
|
|
||
| ```yaml | ||
| - name: hazelcast | ||
| image: hazelcast/hazelcast:5.3.8 | ||
| ports: | ||
| - containerPort: 5702 | ||
| name: hazelcast | ||
| env: | ||
| - name: JAVA_OPTS | ||
| value: >- | ||
| -Dhazelcast.config=/dev/stdin | ||
| -Dhazelcast.local.publicAddress=$(POD_IP):5702 | ||
| - name: HZ_CLUSTERNAME | ||
| value: gerrit-trigger-cluster | ||
| - name: HZ_NETWORK_PORT_PORT | ||
| value: "5702" | ||
| ``` | ||
|
|
||
| Grant the pod's service account read access to Kubernetes endpoints so Hazelcast can | ||
| discover its peers: | ||
|
|
||
| ```yaml | ||
| apiVersion: rbac.authorization.k8s.io/v1 | ||
| kind: ClusterRole | ||
| metadata: | ||
| name: hazelcast-gerrit-trigger | ||
| rules: | ||
| - apiGroups: [""] | ||
| resources: ["endpoints", "pods", "nodes", "services"] | ||
| verbs: ["get", "list"] | ||
| - apiGroups: ["discovery.k8s.io"] | ||
| resources: ["endpointslices"] | ||
| verbs: ["get", "list"] | ||
| ``` | ||
|
|
||
| #### Kubernetes — Client Mode with Separate Hazelcast Cluster | ||
|
|
||
| For larger deployments or strict separation of concerns, you can decouple the coordination layer by running a standalone Hazelcast cluster. Jenkins still connects as a lightweight client, but routes traffic to the separate cluster via a Kubernetes service instead of a sidecar. | ||
|
|
||
| Add the following JVM arguments to the Jenkins instance, updating the client address to point to your standalone Hazelcast Kubernetes service (replace hazelcast-service.default.svc.cluster.local with your actual service DNS and namespace, along with the cluster name for your logical instance): | ||
|
|
||
| -Dgerrit.trigger.coordination.mode=hazelcast | ||
| -Dgerrit.trigger.coordination.hazelcast.client.addresses=hazelcast-service.default.svc.cluster.local:5702 | ||
| -Dgerrit.trigger.coordination.hazelcast.client.cluster.name=gerrit-trigger-cluster-<LOGICAL_INSTANCE_NAME> | ||
|
|
||
| In this topology: | ||
| - You do not need to add the sidecar container to the Jenkins pod spec. | ||
| - The Jenkins service account does not need RBAC permissions for peer discovery, as cluster management is handled entirely by the standalone Hazelcast nodes. | ||
| - You must deploy and manage the Hazelcast cluster independently (e.g. via the official Hazelcast Helm chart), ensuring you configure it to match your expected `HZ_CLUSTERNAME` and port (`5702`). | ||
|
|
||
| (*) Jenkins does not support multiple replicas or nodes for a single logical instance, this feature is not tested with Jenkins. This feature is provided for CloudBees CI (Enterprise Jenkins). | ||
| This feature is provided as a community effort and is not endorsed or officially supported by CloudBees. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,6 +67,7 @@ | |
| <surefire.rerunFailingTestsCount>3</surefire.rerunFailingTestsCount> | ||
| <forkCount>0.5C</forkCount> | ||
| <spotbugs.threshold>High</spotbugs.threshold> | ||
| <hazelcast.version>5.3.8</hazelcast.version> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
|
|
@@ -107,6 +108,11 @@ | |
| </exclusions> | ||
| <!-- New source is here: https://github.com/sonyxperiadev/gerrit-events --> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.hazelcast</groupId> | ||
| <artifactId>hazelcast</artifactId> | ||
| <version>${hazelcast.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>io.jenkins.plugins</groupId> | ||
| <artifactId>gson-api</artifactId> | ||
|
|
@@ -203,6 +209,12 @@ | |
| <artifactId>workflow-support</artifactId> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
| <artifactId>workflow-support</artifactId> | ||
| <classifier>tests</classifier> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <!-- Used for test with matrix permissions --> | ||
| <groupId>org.jenkins-ci.plugins</groupId> | ||
|
|
@@ -370,6 +382,42 @@ | |
| </plugins> | ||
| </build> | ||
|
|
||
| <profiles> | ||
| <!-- | ||
| Profile for testing with Hazelcast coordination mode enabled. | ||
| Usage: mvn clean test -Ptest-hazelcast | ||
|
|
||
| This profile enables Hazelcast distributed coordination during tests to verify: | ||
| - HazelcastCoordinationProvider is selected | ||
| - HazelcastBuildMemoryStorage works correctly | ||
| - Event and notification claiming strategies work | ||
|
|
||
| An embedded Hazelcast server is automatically started before any tests run by | ||
| HazelcastServerTestListener (discovered via | ||
| META-INF/services/org.junit.platform.launcher.TestExecutionListener). This provides | ||
| the localhost:5702 endpoint that the plugin client connects to, with no external | ||
| Kubernetes or TCP infrastructure required. | ||
| --> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So thiss means that there will be no hazelcastt specific tests at all during norrmal CI builds? I remember we discussed that we'll need at least one smoke test durng the normal run to have some indication that future work doesn't break the hazelcast coordination mode. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added with 5887ec3 |
||
| <profile> | ||
| <id>test-hazelcast</id> | ||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <configuration> | ||
| <reuseForks>false</reuseForks> | ||
| <forkCount>1</forkCount> | ||
| <systemPropertyVariables> | ||
| <!-- Enable Hazelcast coordination mode for tests --> | ||
| <gerrit.trigger.coordination.mode>hazelcast</gerrit.trigger.coordination.mode> | ||
| </systemPropertyVariables> | ||
| </configuration> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </profile> | ||
| </profiles> | ||
|
|
||
| <scm> | ||
| <connection>scm:git:https://github.com/${gitHubRepo}.git</connection> | ||
| <developerConnection>scm:git:git@github.com:${gitHubRepo}.git</developerConnection> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any interaction with / relationship to #1017?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@panicking claims that they shouldn't break eachother. I am about to review it to check.