You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hudi.apache.org by "rahil-c (via GitHub)" <gi...@apache.org> on 2026/08/19 23:47:02 UTC

[PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

rahil-c opened a new pull request, #19677:
URL: https://github.com/apache/hudi/pull/19677

   ### Describe the issue this Pull Request addresses
   
   Closes #19675
   
   ### Summary and Changelog
   
   Fixes the defects that stop `UnstructuredFileDFSSource` working on real folders, plus several smaller ones in the same code paths.
   
   Discovery moves off `DFSPathSelector` onto a selector belonging to this source, which fixes three problems at once. Selected files are returned as a list rather than a comma-joined string, so a filename containing a comma no longer tears apart and fails the batch. Batches are bounded by file count through a new `hoodie.streamer.source.unstructured.max.files.per.batch`, since `--source-limit` bounds only bytes while file count is what drives driver memory. The checkpoint carries `(modificationTime, lastPath)` rather than a bare timestamp, which lets a group of files sharing one modification time be split across syncs without the remainder being stranded by the next sync's `mtime > checkpoint` filter. A legacy timestamp-only checkpoint keeps its previous meaning, so upgrading re-ingests nothing. `DFSPathSelector` itself is untouched, so other DFS-based sources are unaffected.
   
   Each selected file now carries the size and modification time the driver learned while listing, removing a second round of metadata requests from the executors.
   
   Also in this PR: the chunk-boundary search is bounded to its acceptable window instead of scanning to the start of the document; `TikaDocumentParser` catches `Exception` so an `Error` propagates rather than becoming a `FAILED` row; the embedding worker pool is released on task completion however the task ends; embedding HTTP clients are shared per JVM instead of created per partition; `blob.inline.max.bytes` is validated against `Integer.MAX_VALUE`; and out-of-line blob references record the ingested length in the field already present in the schema.
   
   ### Impact
   
   One new config, `hoodie.streamer.source.unstructured.max.files.per.batch`, defaulting to 10000. Existing tables are unaffected: the checkpoint format change is backward compatible, and out-of-line references gain a value in a field that was previously written as null. No public API, storage format or bundle change.
   
   ### Risk Level
   
   low
   
   Contained to `hudi-utilities` and to a source and transformer that are opt-in. Every fix has a test that fails without it, verified by reverting each one. Beyond unit tests, each of the three selector problems was reproduced and then re-run end to end through HoodieStreamer on Spark 3.5.5: a corpus containing a comma in a filename, a 2 GB corpus of 64,487 files at the default source limit that previously exhausted an 8 GB driver, and a 25,167-file corpus sharing one modification time under a 64 MiB limit that previously ingested 800 MiB.
   
   ### Documentation Update
   
   The new config carries `@ConfigClassProperty` documentation and generates into the config reference. No website change is needed; the source and transformer are not yet documented on the site.
   
   ### Contributor's checklist
   
   - [x] Read through [contributor's guide](https://hudi.apache.org/contribute/how-to-contribute)
   - [x] Enough context is provided in the sections above
   - [x] Adequate tests were added if applicable
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-bot (via GitHub)" <gi...@apache.org>.
hudi-bot commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5386917448

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "status" : "FAILURE",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396",
       "triggerID" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "triggerType" : "PUSH"
     }, {
       "hash" : "592afb17bc15189b95a0c8b9c3528061ea528088",
       "status" : "UNKNOWN",
       "url" : "TBD",
       "triggerID" : "592afb17bc15189b95a0c8b9c3528061ea528088",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * a5170e034d31dc66a295c072553525dfa12de48d Azure: [FAILURE](https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396) 
   * 592afb17bc15189b95a0c8b9c3528061ea528088 UNKNOWN
   
   <details>
   <summary>Bot commands</summary>
     @hudi-bot supports the following commands:
   
    - `@hudi-bot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-bot (via GitHub)" <gi...@apache.org>.
hudi-bot commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5386944298

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "status" : "FAILURE",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396",
       "triggerID" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "triggerType" : "PUSH"
     }, {
       "hash" : "592afb17bc15189b95a0c8b9c3528061ea528088",
       "status" : "PENDING",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16488",
       "triggerID" : "592afb17bc15189b95a0c8b9c3528061ea528088",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * a5170e034d31dc66a295c072553525dfa12de48d Azure: [FAILURE](https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396) 
   * 592afb17bc15189b95a0c8b9c3528061ea528088 Azure: [PENDING](https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16488) 
   
   <details>
   <summary>Bot commands</summary>
     @hudi-bot supports the following commands:
   
    - `@hudi-bot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-bot (via GitHub)" <gi...@apache.org>.
hudi-bot commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5349966034

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "status" : "FAILURE",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396",
       "triggerID" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * a5170e034d31dc66a295c072553525dfa12de48d Azure: [FAILURE](https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396) 
   
   <details>
   <summary>Bot commands</summary>
     @hudi-bot supports the following commands:
   
    - `@hudi-bot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "voonhous (via GitHub) via commits" <co...@hudi.apache.org>.
voonhous commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-6701311575

   Temporarily closing this PR while we debug a GitHub settings error on master (#20471); it will be reopened shortly, no action needed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-bot (via GitHub)" <gi...@apache.org>.
hudi-bot commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5387188084

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "status" : "DELETED",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396",
       "triggerID" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "triggerType" : "PUSH"
     }, {
       "hash" : "592afb17bc15189b95a0c8b9c3528061ea528088",
       "status" : "FAILURE",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16488",
       "triggerID" : "592afb17bc15189b95a0c8b9c3528061ea528088",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * 592afb17bc15189b95a0c8b9c3528061ea528088 Azure: [FAILURE](https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16488) 
   
   <details>
   <summary>Bot commands</summary>
     @hudi-bot supports the following commands:
   
    - `@hudi-bot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "rahil-c (via GitHub)" <gi...@apache.org>.
rahil-c commented on code in PR #19677:
URL: https://github.com/apache/hudi/pull/19677#discussion_r3834371629


##########
hudi-utilities/src/main/java/org/apache/hudi/utilities/config/UnstructuredFileSourceConfig.java:
##########
@@ -122,6 +122,15 @@ public class UnstructuredFileSourceConfig extends HoodieConfig {
       .sinceVersion("1.2.0")
       .withDocumentation("Number of characters consecutive chunks overlap by.");
 
+  public static final ConfigProperty<Integer> MAX_FILES_PER_BATCH = ConfigProperty

Review Comment:
   I am not sure i understand why we would bound by file count, i would assume bounding by bytes seems to be safer? Can you explain the pros and cons for each



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5349489497

   ## [Codecov](https://app.codecov.io/gh/apache/hudi/pull/19677?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   :white_check_mark: All modified and coverable lines are covered by tests.
   :white_check_mark: Project coverage is 77.83%. Comparing base ([`5a11a4f`](https://app.codecov.io/gh/apache/hudi/commit/5a11a4fce20620afac143358bc771dfe2d14d3c8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`a5170e0`](https://app.codecov.io/gh/apache/hudi/commit/a5170e034d31dc66a295c072553525dfa12de48d?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
   
   <details><summary>Additional details and impacted files</summary>
   
   
   
   ```diff
   @@             Coverage Diff              @@
   ##             master   #19677      +/-   ##
   ============================================
   - Coverage     77.83%   77.83%   -0.01%     
   + Complexity    33140    33132       -8     
   ============================================
     Files          2527     2527              
     Lines        139942   139911      -31     
     Branches      16849    16847       -2     
   ============================================
   - Hits         108926   108896      -30     
     Misses        23396    23396              
   + Partials       7620     7619       -1     
   ```
   
   | [Components](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=components&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [hudi-common](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `83.34% <ø> (ø)` | |
   | [hudi-client](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `82.82% <ø> (-0.01%)` | :arrow_down: |
   | [hudi-flink](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `85.75% <ø> (ø)` | |
   | [hudi-spark-datasource](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `72.27% <ø> (ø)` | |
   | [hudi-utilities](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `73.99% <ø> (-0.05%)` | :arrow_down: |
   | [hudi-cli](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `15.06% <ø> (ø)` | |
   | [hudi-hadoop](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `69.09% <ø> (ø)` | |
   | [hudi-sync](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `75.58% <ø> (ø)` | |
   | [hudi-io](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `79.85% <ø> (ø)` | |
   | [hudi-timeline-service](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `83.44% <ø> (ø)` | |
   | [hudi-cloud](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `64.33% <ø> (ø)` | |
   | [hudi-kafka-connect](https://app.codecov.io/gh/apache/hudi/pull/19677/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `53.20% <ø> (ø)` | |
   
   | [Flag](https://app.codecov.io/gh/apache/hudi/pull/19677/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [hadoop-mr-java-client](https://app.codecov.io/gh/apache/hudi/pull/19677/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `43.89% <ø> (-0.02%)` | :arrow_down: |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/hudi/pull/19677?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [...utilities/config/UnstructuredFileSourceConfig.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Fconfig%2FUnstructuredFileSourceConfig.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL2NvbmZpZy9VbnN0cnVjdHVyZWRGaWxlU291cmNlQ29uZmlnLmphdmE=) | `98.41% <ø> (ø)` | |
   | [...i/utilities/sources/UnstructuredFileDFSSource.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Fsources%2FUnstructuredFileDFSSource.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3NvdXJjZXMvVW5zdHJ1Y3R1cmVkRmlsZURGU1NvdXJjZS5qYXZh) | `85.41% <ø> (-2.09%)` | :arrow_down: |
   | [...s/sources/helpers/unstructured/DocumentParser.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Fsources%2Fhelpers%2Funstructured%2FDocumentParser.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3NvdXJjZXMvaGVscGVycy91bnN0cnVjdHVyZWQvRG9jdW1lbnRQYXJzZXIuamF2YQ==) | `100.00% <ø> (ø)` | |
   | [...ties/sources/helpers/unstructured/TextChunker.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Fsources%2Fhelpers%2Funstructured%2FTextChunker.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3NvdXJjZXMvaGVscGVycy91bnN0cnVjdHVyZWQvVGV4dENodW5rZXIuamF2YQ==) | `92.59% <ø> (+2.27%)` | :arrow_up: |
   | [...urces/helpers/unstructured/TikaDocumentParser.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Fsources%2Fhelpers%2Funstructured%2FTikaDocumentParser.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3NvdXJjZXMvaGVscGVycy91bnN0cnVjdHVyZWQvVGlrYURvY3VtZW50UGFyc2VyLmphdmE=) | `100.00% <ø> (ø)` | |
   | [...rs/unstructured/UnstructuredFileRecordBuilder.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Fsources%2Fhelpers%2Funstructured%2FUnstructuredFileRecordBuilder.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3NvdXJjZXMvaGVscGVycy91bnN0cnVjdHVyZWQvVW5zdHJ1Y3R1cmVkRmlsZVJlY29yZEJ1aWxkZXIuamF2YQ==) | `82.97% <ø> (-1.34%)` | :arrow_down: |
   | [...ties/transform/embedding/EmbeddingTransformer.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Ftransform%2Fembedding%2FEmbeddingTransformer.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3RyYW5zZm9ybS9lbWJlZGRpbmcvRW1iZWRkaW5nVHJhbnNmb3JtZXIuamF2YQ==) | `88.88% <ø> (+0.70%)` | :arrow_up: |
   | [...m/embedding/OpenAICompatibleEmbeddingProvider.java](https://app.codecov.io/gh/apache/hudi/pull/19677?src=pr&el=tree&filepath=hudi-utilities%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fhudi%2Futilities%2Ftransform%2Fembedding%2FOpenAICompatibleEmbeddingProvider.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVkaS11dGlsaXRpZXMvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1ZGkvdXRpbGl0aWVzL3RyYW5zZm9ybS9lbWJlZGRpbmcvT3BlbkFJQ29tcGF0aWJsZUVtYmVkZGluZ1Byb3ZpZGVyLmphdmE=) | `83.09% <ø> (-0.69%)` | :arrow_down: |
   
   ... and [1 file with indirect coverage changes](https://app.codecov.io/gh/apache/hudi/pull/19677/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   </details>
   <details><summary> :rocket: New features to boost your workflow: </summary>
   
   - :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
   - :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-bot (via GitHub)" <gi...@apache.org>.
hudi-bot commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5349459845

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "status" : "PENDING",
       "url" : "https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396",
       "triggerID" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * a5170e034d31dc66a295c072553525dfa12de48d Azure: [PENDING](https://dev.azure.com/apachehudi/a1a51da7-8592-47d4-88dc-fd67bed336bb/_build/results?buildId=16396) 
   
   <details>
   <summary>Bot commands</summary>
     @hudi-bot supports the following commands:
   
    - `@hudi-bot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-agent (via GitHub)" <gi...@apache.org>.
hudi-agent commented on code in PR #19677:
URL: https://github.com/apache/hudi/pull/19677#discussion_r3846020390


##########
hudi-utilities/src/main/java/org/apache/hudi/utilities/transform/embedding/EmbeddingTransformer.java:
##########
@@ -262,16 +277,60 @@ private void submitUpToWindow() {
       }
     }
 
-    private ExecutorService executor() {
+    private synchronized ExecutorService executor() {
       if (executor == null) {
         executor = Executors.newFixedThreadPool(maxInflight,
             new CustomizedThreadFactory("embedding-transformer", true));
+        // end() runs only once the input drains normally. A task killed by an embeddings
+        // failure would otherwise strand maxInflight threads on an executor JVM that Spark
+        // goes on reusing, so release them on task completion however the task ends.
+        TaskContext taskContext = TaskContext.get();
+        if (taskContext != null) {
+          taskContext.addTaskCompletionListener(
+              (TaskCompletionListener) context -> shutdownExecutor());
+        }
       }
       return executor;
     }
 
+    private synchronized void shutdownExecutor() {
+      if (executor != null) {
+        executor.shutdownNow();
+        executor = null;
+      }
+    }
+
     private List<float[]> embed(List<String> texts) {
-      return providerInstance().embed(texts);
+      Semaphore permits = permits(maxConcurrent);
+      try {
+        permits.acquire();
+      } catch (InterruptedException e) {
+        Thread.currentThread().interrupt();
+        throw new HoodieException("Interrupted waiting to call the embeddings API", e);
+      }
+      try {
+        return providerInstance().embed(texts);
+      } finally {
+        permits.release();
+      }
+    }
+
+    /**
+     * Caps embedding requests in flight across the whole JVM. Each partition runs its own worker
+     * pool, so without a shared limit the load offered to one endpoint is
+     * (concurrent tasks x max.inflight.requests) and grows with the cluster: an oversubscribed
+     * endpoint then returns timeouts or 429s, which retry, which adds more load. Queueing here
+     * instead is free, since a waiting thread holds no connection and nothing can time out
+     * while it waits.
+     *
+     * <p>Every task configured alike shares one semaphore, which is what makes the cap hold
+     * across partitions. Executors are long lived and reused, so keying by permit count keeps a
+     * second job with a different setting on its own budget rather than silently inheriting the
+     * first job's.
+     */
+    @VisibleForTesting

Review Comment:
   🤖 Since the semaphore is keyed only by permit count, two embedding transforms in the same executor JVM that share a `maxConcurrent` value (e.g. both on the default 4) but hit different endpoints would draw on one semaphore — a combined cap of 4, not 4 per endpoint. Is that intended, or should the provider/endpoint identity be part of the key so the doc's "requests to the endpoint" framing holds?
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.</i></sub>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-bot (via GitHub)" <gi...@apache.org>.
hudi-bot commented on PR #19677:
URL: https://github.com/apache/hudi/pull/19677#issuecomment-5349421010

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "status" : "UNKNOWN",
       "url" : "TBD",
       "triggerID" : "a5170e034d31dc66a295c072553525dfa12de48d",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * a5170e034d31dc66a295c072553525dfa12de48d UNKNOWN
   
   <details>
   <summary>Bot commands</summary>
     @hudi-bot supports the following commands:
   
    - `@hudi-bot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "rahil-c (via GitHub)" <gi...@apache.org>.
rahil-c commented on code in PR #19677:
URL: https://github.com/apache/hudi/pull/19677#discussion_r3834385729


##########
hudi-utilities/src/main/java/org/apache/hudi/utilities/sources/helpers/unstructured/UnstructuredFilePathSelector.java:
##########
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hudi.utilities.sources.helpers.unstructured;
+
+import org.apache.hudi.common.config.TypedProperties;
+import org.apache.hudi.common.table.checkpoint.Checkpoint;
+import org.apache.hudi.common.util.Option;
+import org.apache.hudi.common.util.ValidationUtils;
+import org.apache.hudi.common.util.VisibleForTesting;
+import org.apache.hudi.exception.HoodieIOException;
+import org.apache.hudi.hadoop.fs.HadoopFSUtils;
+import org.apache.hudi.utilities.config.DFSPathSelectorConfig;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.apache.hudi.common.table.checkpoint.CheckpointUtils.createCheckpoint;
+import static org.apache.hudi.common.util.ConfigUtils.getIntWithAltKeys;
+import static org.apache.hudi.common.util.ConfigUtils.getStringWithAltKeys;
+import static org.apache.hudi.utilities.config.UnstructuredFileSourceConfig.MAX_FILES_PER_BATCH;
+
+/**
+ * Selects the next batch of files for {@code UnstructuredFileDFSSource}.
+ *
+ * <p>Differs from {@link org.apache.hudi.utilities.sources.helpers.DFSPathSelector} in three ways
+ * that matter at scale:
+ *
+ * <ul>
+ *   <li>The batch is bounded by file <em>count</em> as well as bytes. A byte budget alone never
+ *       bounds the number of files, and file count is what drives driver memory and task count.</li>
+ *   <li>The checkpoint carries {@code (modificationTime, lastPath)} rather than a bare timestamp,
+ *       so a group of files sharing one modification time can be split across syncs without the
+ *       unread remainder being stranded by a {@code mtime > checkpoint} filter. Files arriving in
+ *       one bulk upload routinely share a timestamp, and object stores report modification times
+ *       at second granularity.</li>
+ *   <li>Selected files are returned as a list of {@code (path, size, modificationTime)} rather
+ *       than one comma-joined string. Paths legitimately contain commas, and re-splitting on one
+ *       corrupts them.</li>
+ * </ul>
+ */
+public class UnstructuredFilePathSelector implements Serializable {

Review Comment:
   Can you explain to me the pros and cons for why we are moving off of DFSPathSelector? If we do not go with file count approach then this class would not be useful right?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "hudi-agent (via GitHub)" <gi...@apache.org>.
hudi-agent commented on code in PR #19677:
URL: https://github.com/apache/hudi/pull/19677#discussion_r3834729602


##########
hudi-utilities/src/main/java/org/apache/hudi/utilities/config/UnstructuredFileSourceConfig.java:
##########
@@ -122,6 +122,15 @@ public class UnstructuredFileSourceConfig extends HoodieConfig {
       .sinceVersion("1.2.0")
       .withDocumentation("Number of characters consecutive chunks overlap by.");
 
+  public static final ConfigProperty<Integer> MAX_FILES_PER_BATCH = ConfigProperty

Review Comment:
   🤖 Worth noting the two bounds aren't mutually exclusive — `selectNextBatch` still honors `sourceLimit` (bytes) at line 201 *and* `maxFilesPerBatch` at line 198, whichever trips first. The reason a byte-only bound isn't sufficient: it never caps the *number* of files, and file count is what drives driver-side memory and task count. A folder of many tiny files stays well under any byte budget yet can still pull the whole corpus into one sync. So bytes protects against a few huge files, file count protects against many small ones — keeping both covers both failure modes.



##########
hudi-utilities/src/main/java/org/apache/hudi/utilities/sources/helpers/unstructured/UnstructuredFilePathSelector.java:
##########
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hudi.utilities.sources.helpers.unstructured;
+
+import org.apache.hudi.common.config.TypedProperties;
+import org.apache.hudi.common.table.checkpoint.Checkpoint;
+import org.apache.hudi.common.util.Option;
+import org.apache.hudi.common.util.ValidationUtils;
+import org.apache.hudi.common.util.VisibleForTesting;
+import org.apache.hudi.exception.HoodieIOException;
+import org.apache.hudi.hadoop.fs.HadoopFSUtils;
+import org.apache.hudi.utilities.config.DFSPathSelectorConfig;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.apache.hudi.common.table.checkpoint.CheckpointUtils.createCheckpoint;
+import static org.apache.hudi.common.util.ConfigUtils.getIntWithAltKeys;
+import static org.apache.hudi.common.util.ConfigUtils.getStringWithAltKeys;
+import static org.apache.hudi.utilities.config.UnstructuredFileSourceConfig.MAX_FILES_PER_BATCH;
+
+/**
+ * Selects the next batch of files for {@code UnstructuredFileDFSSource}.
+ *
+ * <p>Differs from {@link org.apache.hudi.utilities.sources.helpers.DFSPathSelector} in three ways
+ * that matter at scale:
+ *
+ * <ul>
+ *   <li>The batch is bounded by file <em>count</em> as well as bytes. A byte budget alone never
+ *       bounds the number of files, and file count is what drives driver memory and task count.</li>
+ *   <li>The checkpoint carries {@code (modificationTime, lastPath)} rather than a bare timestamp,
+ *       so a group of files sharing one modification time can be split across syncs without the
+ *       unread remainder being stranded by a {@code mtime > checkpoint} filter. Files arriving in
+ *       one bulk upload routinely share a timestamp, and object stores report modification times
+ *       at second granularity.</li>
+ *   <li>Selected files are returned as a list of {@code (path, size, modificationTime)} rather
+ *       than one comma-joined string. Paths legitimately contain commas, and re-splitting on one
+ *       corrupts them.</li>
+ * </ul>
+ */
+public class UnstructuredFilePathSelector implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+  private static final ObjectMapper MAPPER = new ObjectMapper();
+  private static final List<String> IGNORE_FILE_PREFIXES = Arrays.asList(".", "_");
+
+  private final String rootPath;
+  private final int maxFilesPerBatch;
+  private final transient Configuration hadoopConf;
+
+  public UnstructuredFilePathSelector(TypedProperties props, Configuration hadoopConf) {
+    this.rootPath = getStringWithAltKeys(props, DFSPathSelectorConfig.ROOT_INPUT_PATH);
+    this.maxFilesPerBatch = getIntWithAltKeys(props, MAX_FILES_PER_BATCH);
+    // a non-positive cap would select nothing, leave the checkpoint untouched, and stall every
+    // subsequent sync without ever failing
+    ValidationUtils.checkArgument(maxFilesPerBatch > 0,
+        MAX_FILES_PER_BATCH.key() + " must be positive, got " + maxFilesPerBatch);
+    this.hadoopConf = hadoopConf;
+  }
+
+  /**
+   * One selected file, carrying what the driver already learned from listing so executors do not
+   * have to stat it a second time.
+   */
+  public static class FileEntry implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public final String path;
+    public final long size;
+    public final long modificationTime;
+
+    public FileEntry(String path, long size, long modificationTime) {
+      this.path = path;
+      this.size = size;
+      this.modificationTime = modificationTime;
+    }
+  }
+
+  /**
+   * The files chosen for one sync and the checkpoint to record if it commits.
+   */
+  public static class Batch {
+    public final List<FileEntry> files;
+    public final Checkpoint checkpoint;
+
+    Batch(List<FileEntry> files, Checkpoint checkpoint) {
+      this.files = files;
+      this.checkpoint = checkpoint;
+    }
+  }
+
+  /**
+   * Position in the source folder: everything at an earlier modification time, plus everything at
+   * this modification time whose path sorts at or before {@code lastPath}, has been ingested.
+   */
+  @VisibleForTesting
+  static class Position {
+    final long modificationTime;
+    final String lastPath;
+
+    Position(long modificationTime, String lastPath) {
+      this.modificationTime = modificationTime;
+      this.lastPath = lastPath;
+    }
+
+    /** True when this file still needs ingesting. */
+    boolean isAfter(FileStatus file) {
+      if (file.getModificationTime() != modificationTime) {
+        return file.getModificationTime() > modificationTime;
+      }
+      // same timestamp: only the tail of the group beyond lastPath remains. A checkpoint written
+      // by the old timestamp-only format has no lastPath, and treating the whole group as done
+      // preserves the previous behaviour rather than re-ingesting it on upgrade.

Review Comment:
   🤖 nit: `from.isAfter(status)` reads as "the position is after the file," but the intent (per the Javadoc) is "this file still needs ingesting." Something like `from.isUnread(status)` or `from.needsIngestion(status)` would make the call site self-explanatory without requiring the reader to cross-reference the doc.
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.</i></sub>



##########
hudi-utilities/src/main/java/org/apache/hudi/utilities/sources/helpers/unstructured/UnstructuredFilePathSelector.java:
##########
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hudi.utilities.sources.helpers.unstructured;
+
+import org.apache.hudi.common.config.TypedProperties;
+import org.apache.hudi.common.table.checkpoint.Checkpoint;
+import org.apache.hudi.common.util.Option;
+import org.apache.hudi.common.util.ValidationUtils;
+import org.apache.hudi.common.util.VisibleForTesting;
+import org.apache.hudi.exception.HoodieIOException;
+import org.apache.hudi.hadoop.fs.HadoopFSUtils;
+import org.apache.hudi.utilities.config.DFSPathSelectorConfig;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.apache.hudi.common.table.checkpoint.CheckpointUtils.createCheckpoint;
+import static org.apache.hudi.common.util.ConfigUtils.getIntWithAltKeys;
+import static org.apache.hudi.common.util.ConfigUtils.getStringWithAltKeys;
+import static org.apache.hudi.utilities.config.UnstructuredFileSourceConfig.MAX_FILES_PER_BATCH;
+
+/**
+ * Selects the next batch of files for {@code UnstructuredFileDFSSource}.
+ *
+ * <p>Differs from {@link org.apache.hudi.utilities.sources.helpers.DFSPathSelector} in three ways
+ * that matter at scale:
+ *
+ * <ul>
+ *   <li>The batch is bounded by file <em>count</em> as well as bytes. A byte budget alone never
+ *       bounds the number of files, and file count is what drives driver memory and task count.</li>
+ *   <li>The checkpoint carries {@code (modificationTime, lastPath)} rather than a bare timestamp,
+ *       so a group of files sharing one modification time can be split across syncs without the
+ *       unread remainder being stranded by a {@code mtime > checkpoint} filter. Files arriving in
+ *       one bulk upload routinely share a timestamp, and object stores report modification times
+ *       at second granularity.</li>
+ *   <li>Selected files are returned as a list of {@code (path, size, modificationTime)} rather
+ *       than one comma-joined string. Paths legitimately contain commas, and re-splitting on one
+ *       corrupts them.</li>
+ * </ul>
+ */
+public class UnstructuredFilePathSelector implements Serializable {

Review Comment:
   🤖 Even setting the file-count feature aside, this class still earns its keep — the class javadoc (lines 54-68) lists two other fixes that are independent of file-count bounding: selected files are returned as a `List<FileEntry>` instead of a comma-joined string (so paths containing commas aren't torn apart), and the checkpoint carries `(modificationTime, lastPath)` instead of a bare timestamp (so a group of files sharing one mtime can be split across syncs without the remainder being stranded by the `mtime > checkpoint` filter). Both are real correctness bugs in DFSPathSelector for this source, so the selector remains useful regardless of whether the file-count cap stays.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] fix(utilities): harden the unstructured file source and embedding transformer [hudi]

Posted by "voonhous (via GitHub) via commits" <co...@hudi.apache.org>.
voonhous closed pull request #19677: fix(utilities): harden the unstructured file source and embedding transformer
URL: https://github.com/apache/hudi/pull/19677


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org