Skip to content

Commit 3e4fe51

Browse files
committed
Merge remote-tracking branch 'origin/master' into codex-review-pr-37904
# Conflicts: # CHANGES.md
2 parents 3af9937 + 268ae1a commit 3e4fe51

1,043 files changed

Lines changed: 18182 additions & 31238 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agent/skills/adding-new-metadata/SKILL.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ You must ensure that when a DoFn processes an element and outputs a new element,
8888
### Timers
8989
If metadata needs to survive timer firings (e.g., knowing an `@OnTimer` fired because of a system drain), it must be added to Timer data structures. This is a bit of uncharted area which was only implemented for CausedByDrain metadata that comes from backend, not from persisted metadata. In order to persist all WindowedValue metadata across timer, more work has to be done, below are some pointers:
9090
* `runners/core-java/src/main/java/org/apache/beam/runners/core/TimerInternals.java` and implementations (e.g., `WindmillTimerInternals.java` in Dataflow).
91-
* `runners/samza/src/test/java/org/apache/beam/runners/samza/runtime/KeyedTimerData.java` (or generic `TimerData`).
9291
* **Action:** Add the field to `TimerData`, next to `CausedByDrain`. Propagate it when setting the timer and expose it when the timer fires so it bubbles up.
9392
* Eventually, metadata from Timer lands in WindowedValue, so it can be exposed to users. Keep field names, types, and getters similar to WindowedValue as much as possible, as common interface may be introduced eventually.
9493

@@ -116,4 +115,4 @@ User needs to access the metadata in their `DoFn` (e.g., `@ProcessElement public
116115
9. [ ] Update `ReduceFnRunner` and `OutputAndTimeBoundedSplittableProcessElementInvoker` for complex transform propagation.
117116
10. [ ] If required by timers, update `TimerData` and `TimerInternals`.
118117
11. [ ] If exposed to the user, update `DoFnSignatures` and `ByteBuddyDoFnInvokerFactory`.
119-
12. [ ] Update other runners (Flink, Spark, Samza) to ensure they propagate the new `WindowedValue` fields correctly in their specific operators/runners.
118+
12. [ ] Update other runners (Flink, Spark) to ensure they propagate the new `WindowedValue` fields correctly in their specific operators/runners.
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
---
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
---
19+
name: beam-dofn-modernizer
20+
description: Rewrite Apache Beam DoFn methods (@ProcessElement, @OnTimer, @OnWindowExpiration) to remove legacy ProcessContext or OnTimerContext usage. Use this skill when you encounter DoFn methods that use context.element(), context.output(), etc., and need to modernize them using parameter injection (@Element, @Timestamp, @Pane, OutputReceiver, MultiOutputReceiver).
21+
---
22+
23+
# Modernizing Apache Beam DoFns
24+
25+
Apache Beam has moved towards parameter injection in `DoFn` methods to improve readability and allow for more efficient execution. This skill helps you migrate legacy `ProcessContext` and `OnTimerContext` usage to modern annotated parameters.
26+
27+
## Core Mappings
28+
29+
When rewriting a `@ProcessElement` or `@OnTimer` method, replace the context argument with the corresponding parameters based on the usage:
30+
31+
| Legacy Context Usage (e.g. `ProcessContext c`) | Modern Parameter Replacement |
32+
| :--- | :--- |
33+
| `c.element()` | `@Element T element` |
34+
| `c.timestamp()` | `@Timestamp Instant timestamp` |
35+
| `c.pane()` | `PaneInfo pane` |
36+
| `c.window()` | `BoundedWindow window` |
37+
| `c.sideInput(PCollectionView<T> view)` | `@SideInput("viewName") T value` |
38+
| `c.getPipelineOptions()` | `PipelineOptions options` |
39+
| `c.output(value)` | `OutputReceiver<T> receiver` then `receiver.output(value)` |
40+
| `c.output(tag, value)` | `MultiOutputReceiver receiver` then `receiver.get(tag).output(value)` |
41+
| `c.outputWithTimestamp(value, ts)` | `OutputReceiver<T> receiver` then `receiver.outputWithTimestamp(value, ts)` |
42+
43+
## Method Signature Changes
44+
45+
### @ProcessElement
46+
47+
**Legacy:**
48+
```java
49+
@ProcessElement
50+
public void processElement(ProcessContext c) {
51+
T element = c.element();
52+
c.output(transform(element));
53+
}
54+
```
55+
56+
**Modern:**
57+
```java
58+
@ProcessElement
59+
public void processElement(
60+
@Element T element,
61+
@Timestamp Instant timestamp,
62+
OutputReceiver<V> receiver) {
63+
receiver.output(transform(element));
64+
}
65+
```
66+
67+
### @OnTimer
68+
69+
**Legacy:**
70+
```java
71+
@OnTimer("timerId")
72+
public void onTimer(OnTimerContext c) {
73+
c.output(someValue);
74+
}
75+
```
76+
77+
**Modern:**
78+
```java
79+
@OnTimer("timerId")
80+
public void onTimer(
81+
@Timestamp Instant timestamp,
82+
BoundedWindow window,
83+
OutputReceiver<V> receiver) {
84+
receiver.output(someValue);
85+
}
86+
```
87+
88+
## Best Practices
89+
90+
1. **Specific OutputReceiver**: If the method only outputs to the main output, use `OutputReceiver<T>`. If it outputs to multiple tags, use `MultiOutputReceiver`.
91+
2. **Element Type**: Ensure the `@Element` parameter type matches the input type of the `DoFn`.
92+
3. **Imports**: Don't forget to add imports for:
93+
* `org.apache.beam.sdk.transforms.DoFn.Element`
94+
* `org.apache.beam.sdk.transforms.DoFn.Timestamp`
95+
* `org.apache.beam.sdk.transforms.DoFn.OutputReceiver`
96+
* `org.apache.beam.sdk.transforms.DoFn.MultiOutputReceiver` (if needed)
97+
* `org.apache.beam.sdk.values.PCollectionView` (if using `@SideInput`)
98+
* `org.apache.beam.sdk.transforms.DoFn.SideInput`
99+
* `org.apache.beam.sdk.transforms.windowing.PaneInfo`
100+
4. **Side Inputs**: When using `@SideInput`, make sure to use the correct name that matches the one passed to `ParDo.withSideInput("name", view)`.
101+
5. **Parameter Naming and Redundant Variables**: Use descriptive names for the `@Element` parameter (e.g., `record`, `line`, `row`) instead of a generic `element` if it improves readability. Do not create a redundant local variable to copy the element (e.g., `MyType elm = element;`), use the parameter directly.
102+
103+
## Example Conversion
104+
105+
### Before:
106+
```java
107+
@ProcessElement
108+
public void processElement(ProcessContext c) {
109+
KV<String, Integer> element = c.element();
110+
Instant ts = c.timestamp();
111+
if (element.getValue() > threshold) {
112+
c.output(element.getKey());
113+
c.output(specialTag, element.getValue());
114+
}
115+
}
116+
```
117+
118+
### After:
119+
```java
120+
@ProcessElement
121+
public void processElement(
122+
@Element KV<String, Integer> element,
123+
@Timestamp Instant timestamp,
124+
MultiOutputReceiver receiver) {
125+
if (element.getValue() > threshold) {
126+
receiver.get(mainTag).output(element.getKey());
127+
receiver.get(specialTag).output(element.getValue());
128+
}
129+
}
130+
```
131+
> [!NOTE]
132+
> If you only have one output, use `OutputReceiver<String> receiver` and `receiver.output(element.getKey())`.
133+
134+
## Side Input Conversion
135+
136+
Modernizing side inputs involves removing the `PCollectionView` from the `DoFn` constructor and using `@SideInput` parameter injection instead.
137+
138+
### Before (Legacy):
139+
140+
**PTransform/Pipeline side:**
141+
```java
142+
PCollectionView<String> myView = ...;
143+
input.apply(ParDo.of(new MyFn(myView)).withSideInputs(myView));
144+
```
145+
146+
**DoFn side:**
147+
```java
148+
class MyFn extends DoFn<T, V> {
149+
private final PCollectionView<String> view;
150+
MyFn(PCollectionView<String> view) { this.view = view; }
151+
152+
@ProcessElement
153+
public void processElement(ProcessContext c) {
154+
String value = c.sideInput(view);
155+
// ...
156+
}
157+
}
158+
```
159+
160+
### Nullable Side Inputs
161+
162+
If a side input is optional and a `DoFn` has conditional logic based on whether the side input is present, it is best to split the `DoFn` into two separate classes: one that requires the side input and one that does not. This avoids creating complex, conditional `DoFn`s and ensures type safety.
163+
164+
**PTransform/Pipeline side:**
165+
```java
166+
PCollectionView<String> myView = ...;
167+
input.apply(ParDo.of(new MyFn(myView)).withSideInputs(myView));
168+
//or
169+
input.apply(ParDo.of(new MyFn(null))); // to introduce null
170+
```
171+
**DoFn side:**
172+
```java
173+
class MyFn extends DoFn<T, V> {
174+
private final PCollectionView<String> view;
175+
MyFn(PCollectionView<String> view) { this.view = view; }
176+
177+
@ProcessElement
178+
public void processElement(ProcessContext c) {
179+
String value = null;
180+
if (this.view != null) { // can do conditional side input
181+
value = c.sideInput(this.view);
182+
}
183+
184+
// ...
185+
}
186+
}
187+
```
188+
189+
### After (Modern):
190+
191+
**PTransform/Pipeline side:**
192+
```java
193+
PCollectionView<String> myView = ...;
194+
input.apply(ParDo.of(new MyFn()).withSideInput("sideInputName", myView));
195+
```
196+
197+
**DoFn side:**
198+
```java
199+
class MyFn extends DoFn<T, V> {
200+
@ProcessElement
201+
public void processElement(
202+
@Element T element,
203+
@SideInput("sideInputName") String value) {
204+
// value is injected directly
205+
}
206+
}
207+
```

.agent/skills/python-development/SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ description: Guides Python SDK development in Apache Beam, including environment
4141
- `pyproject.toml` - Build configuration
4242
- `tox.ini` - Test automation
4343
- `pytest.ini` - Pytest configuration
44-
- `.pylintrc` - Linting rules
44+
- `ruff.toml` - Linting rules
4545
- `.isort.cfg` - Import sorting
46-
- `mypy.ini` - Type checking
46+
- `pyrefly.toml` - Type checking
4747

4848
## Environment Setup
4949

@@ -176,10 +176,10 @@ Use `--requirements_file=requirements.txt` or custom containers.
176176
## Code Quality Tools
177177
```bash
178178
# Linting
179-
pylint apache_beam/
179+
ruff check apache_beam/
180180

181181
# Type checking
182-
mypy apache_beam/
182+
pyrefly check apache_beam/
183183

184184
# Formatting (via yapf)
185185
yapf -i apache_beam/file.py

.agent/skills/runners/SKILL.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ Runners execute Beam pipelines on distributed processing backends. Each runner t
3434
| Dataflow | `runners/google-cloud-dataflow-java/` | Google Cloud Dataflow |
3535
| Flink | `runners/flink/` | Apache Flink |
3636
| Spark | `runners/spark/` | Apache Spark |
37-
| Samza | `runners/samza/` | Apache Samza |
3837
| Jet | `runners/jet/` | Hazelcast Jet |
3938
| Twister2 | `runners/twister2/` | Twister2 |
4039

.asf.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ github:
5151

5252
protected_branches:
5353
master: {}
54+
release-2.73.0-postrelease: {}
5455
release-2.73: {}
5556
release-2.72.0-postrelease: {}
5657
release-2.72: {}

.gemini/config.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ code_review:
4646

4747
# Post code review on PR open.
4848
# Type boolean, default: true.
49-
code_review: false
49+
code_review: true
50+
51+
# Enables agent functionality on draft pull requests.
52+
# Type: boolean, default: true.
53+
include_drafts: false
5054

5155
# List of glob patterns to ignore (files and directories).
5256
# Type: array of string, default: [].

.github/ACTIONS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Currently, we have both GitHub-hosted and self-hosted runners for running the Gi
2828
### Getting Started with self-hosted runners
2929
* Refer to [this README](./gh-actions-self-hosted-runners/README.md) for the steps for creating your own self-hosted runners for testing your workflows.
3030
* Depending on your workflow's needs, it must specify the following `runs-on` tags to run in the specified operating system:
31-
* Ubuntu 20.04 self-hosted runner: `[self-hosted, ubuntu-20.04]`
31+
* Ubuntu 24.04 self-hosted runner: `[self-hosted, ubuntu-24.04, main]` (also `small`, `highmem`, or `highmem22` pool labels as needed)
3232
* Windows Server 2019 self-hosted runner: `[self-hosted, windows-server-2019]`
3333
* MacOS GitHub-hosted runner: `macos-latest`
3434
* Every workflow that tests the source code, needs to have the workflow trigger `pull_request_target` instead of `pull_request`.
@@ -48,7 +48,7 @@ Currently, we have both GitHub-hosted and self-hosted runners for running the Gi
4848
node-version: 16
4949
```
5050
* You can find the GitHub-hosted runner installations in the following links:
51-
* [Ubuntu-20.04](https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2004-Readme.md#installed-apt-packages)
51+
* [Ubuntu-24.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md#installed-apt-packages)
5252
* [Windows-2019](https://github.com/actions/runner-images/blob/main/images/win/Windows2019-Readme.md)
5353
5454
#### GitHub Actions Example
@@ -60,7 +60,7 @@ on:
6060
permissions: read-all
6161
jobs:
6262
github-actions-example:
63-
runs-on: [self-hosted, ubuntu-20.04]
63+
runs-on: [self-hosted, ubuntu-24.04, main]
6464
steps:
6565
- name: Check out repository code
6666
uses: actions/checkout@v2

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ body:
7272
- label: "Component: Infrastructure"
7373
- label: "Component: Spark Runner"
7474
- label: "Component: Flink Runner"
75-
- label: "Component: Samza Runner"
75+
- label: "Component: Prism Runner"
7676
- label: "Component: Twister2 Runner"
7777
- label: "Component: Hazelcast Jet Runner"
7878
- label: "Component: Google Cloud Dataflow Runner"

.github/ISSUE_TEMPLATE/failing_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ body:
7878
- label: "Component: Infrastructure"
7979
- label: "Component: Spark Runner"
8080
- label: "Component: Flink Runner"
81-
- label: "Component: Samza Runner"
81+
- label: "Component: Prism Runner"
8282
- label: "Component: Twister2 Runner"
8383
- label: "Component: Hazelcast Jet Runner"
8484
- label: "Component: Google Cloud Dataflow Runner"

.github/ISSUE_TEMPLATE/feature.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ body:
6666
- label: "Component: Infrastructure"
6767
- label: "Component: Spark Runner"
6868
- label: "Component: Flink Runner"
69-
- label: "Component: Samza Runner"
69+
- label: "Component: Prism Runner"
7070
- label: "Component: Twister2 Runner"
7171
- label: "Component: Hazelcast Jet Runner"
7272
- label: "Component: Google Cloud Dataflow Runner"

0 commit comments

Comments
 (0)