ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java 批量 URI 提取中的部分失败处理:解读 xberg extract_batch 的结果语义与容错实践

Java 批量 URI 提取中的部分失败处理:解读 xberg extract_batch 的结果语义与容错实践 后端AI 应用NLP【免费下载链接】xbergPolyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.项目地址https://gitcode.com/gh_mirrors/kr/xberg点击查看免费下载xberg 的extractBatch允许在单次调用中提交多个URI输入但真实场景里远程文档往往有成功、有失败——例如一个text/plain正常返回而另一个下载成功的 PDF 却是损坏截断文件。本文以仓库中extract_batch_uri_partial_failure这一官方 Java 用例为骨架逐行解读示例代码并深入到 Rust 引擎的实现说明 xberg 如何把部分失败折叠进统一的结果信封ExtractionResult以及你在生产代码中应如何消费summary与errors做容错处理。一、场景一次批量调用两种结局批量提取的核心价值在于合并 I/O 与解析开销但代价是输入之间的失败不再一刀切。extract_batch_uri_partial_failure用例构造的正是这种典型形态定义见 fixtures/batch/extract_batch_uri_partial_failure.json输入URIMock 响应预期结局1$mock_url/text/plain.txt200content-type: text/plain正文来自test_documents/text/plain.txt成功产出 1 个ExtractedDocument2$mock_url/pdf/corrupt_truncated.pdf200content-type: application/pdf正文来自test_documents/pdf/corrupt_truncated.pdf下载成功但文档不可解析记录 1 条错误关键点在于两个 URI 都能被 HTTP 下载均返回 200但第二个文档的字节流无法被 PDF 解析器识别。这属于下载层成功、解析层失败与网络错误、404 不同是文档流水线中最常见的部分失败来源。该用例对应的断言见 fixtures/batch/extract_batch_uri_partial_failure.json也很明确not_error整个批量调用本身成功返回不抛异常summary.results 1恰好 1 个输入产生结果summary.errors 1恰好 1 个输入被记为错误。也就是说部分失败不升级为整批异常而是被折叠进结果信封由调用方自行处置——这正是本文要讲透的语义。二、示例代码逐行解读原用例的 Java 代码出自 docs-site/src/snippets-generated/java/batch/extract_batch_uri_partial_failure.mdimport io.xberg.*; public final class Example { public static void main(String[] args) throws Exception { var result Xberg.extractBatch(java.util.Arrays.asList(JsonUtil.fromJson({\kind\:\uri\,\uri\:\https://example.com/text/plain.txt\}, ExtractInput.class), JsonUtil.fromJson({\kind\:\uri\,\uri\:\https://example.com/pdf/corrupt_truncated.pdf\}, ExtractInput.class)), ExtractionConfig.builder().build()); System.out.println(result.summary().results()); System.out.println(result.summary().errors()); } }几个值得展开的细节JsonUtil.fromJson(..., ExtractInput.class)构造输入ExtractInput是携带kind、bytes、uri等字段的 record见 packages/java/io/xberg/ExtractInput.java。kind为uri时只取uri字段kind为bytes时则需bytes与mime_typekind由枚举 ExtractInputKind 约束其URI值支持文件系统路径、file://URI 以及 HTTP(S) URL。用 JSON 字符串构造的优势是字段名与 Rust 侧序列化格式一一对应也便于在运行时动态生成输入。ExtractionConfig.builder().build()直接使用默认配置。这意味着格式检测、OCR、分块等全部采用内置默认值是开箱即用的写法。ExtractInput还支持按输入覆盖配置config字段可以在批量内对单个文档施加差异化参数。result.summary().results()与result.summary().errors()summary()返回ExtractionSummary是批量调用的体检表先读它再决定是否遍历results()是消费批量结果的标准姿势。main声明throws ExceptionXberg.extractBatch在 FFI 层失败如配置非法、序列化失败时抛XbergRsException见 packages/java/io/xberg/XbergRs.java而单个输入的错误不会抛出只进入errors列表。这也是部分失败与整批失败的分界线。三、结果信封summary 告诉你成败比例extractBatch的返回值类型是统一的ExtractionResultpackages/java/io/xberg/ExtractionResult.java包含五组信息字段Java 访问器含义resultsresults()按发现顺序排列的ExtractedDocument列表errorserrors()非致命的逐输入错误列表ExtractionErrorItemsummarysummary()聚合计数见下表crawl_final_urlscrawlFinalUrls()URL 抓取中经重定向后的最终 URLcrawl_redirect_countcrawlRedirectCount()抓取/爬取过程中跟随的重定向总数其中summary对应 Rust 侧的ExtractionSummary定义见 crates/xberg/src/core/config/extraction/types.rsJava 侧为 packages/java/io/xberg/ExtractionSummary.java字段含义本用例取值inputs调用方提交的输入总数2results成功产出文档的数量1errors逐输入错误数量1remote_urls解析为远程 HTTP(S) 的 URI 输入数2pages_crawled被抓取/抓取的 HTML 页面数0documents_downloaded从 URL 下载的非 HTML 文档数1纯文本被提取注意results errors通常等于inputs但不绝对——例如 URI 输入触发的爬取会展开出多个页面此时页面数单独统计。每个错误条目ExtractionErrorItempackages/java/io/xberg/ExtractionErrorItem.java携带定位与排查所需的全部信息字段含义index出错输入在inputs列表中的下标从 0 开始code数值错误码error_type字符串形式的错误类型source尽力而为的源标识通常是 URI 或文件名message人类可读的错误消息在本用例中errors里应有一条index 1、source https://example.com/pdf/corrupt_truncated.pdf的记录——index直接告诉你第几个输入挂了source告诉你是哪个 URL 挂了。四、底层原理Rust 引擎如何聚合部分失败Java 绑定只是把ListExtractInput与ExtractionConfig序列化为 JSON经 FFI 调用XBERG_EXTRACT_BATCH后反序列化回ExtractionResult见 packages/java/io/xberg/XbergRs.java。真正的语义在 Rust 引擎crates/xberg/src/engine/extract_impl.rs中定义。1. 入口与缓存extract_batchextract_impl.rs的流程是先校验配置config.validate()再以输入列表 配置计算批量缓存键batch_content_cache_key命中缓存则直接返回。缓存写入有一个重要前提见 L270-L278if output.errors.is_empty() let Some(key) cache_key let Ok(serialized) serde_json::to_vec(output) { inner.cache.put(key, serialized, None).await; }也就是说只要批量里存在任何错误本次结果就不会写入缓存。这保证了坏文档被修复后重试不会命中陈旧的失败结果——从源码结构看这是刻意为之的容错设计。2. 并发与顺序两种执行路径extract_batch_uncachedextract_impl.rs根据编译特性选择执行策略启用tokio-runtime且非wasm32时走extract_batch_concurrent在tokio::task::JoinSet上并发执行各输入否则走extract_batch_sequentialextract_impl.rs逐个 await。顺序路径的逻辑最能体现部分失败的折叠方式初始化summary.inputs inputs.len()然后对每个输入调用extract_one成功结果被收集进output.results失败则被output.errors.push(error_item(index, source, error))捕获见 L369-L380整个循环不会因单个输入失败而中断。3. 输入分发与错误条目构造extract_oneextract_impl.rs先通过resolve_input_config把ExtractInput自带的config覆盖合并进批量级配置含按批次均摊线程预算、取消令牌等再在extract_one_resolved中按kind分发到extract_bytes_input或extract_uri_input。错误条目由 error_item 统一构造fn error_item(index: usize, source: String, error: XbergError) - ExtractionErrorItem { ExtractionErrorItem { index, code: error_code(error), error_type: error_type(error).to_string(), source, message: error.to_string(), } }这解释了 Java 侧index / code / error_type / source / message五个字段的来历它们不是绑定层拼装的而是 Rust 引擎在每个输入失败时原地生成的结构化数据。4. 损坏 PDF 为什么失败corrupt_truncated.pdf是仓库中刻意保留的坏样本。在 crates/xberg/src/extractors/pdf/mod.rs 的注释中可以看到它是test_documents/里唯一一个击穿原生 PDF 解析器计数、无法被读取的文档。相关单元测试extractors/pdf/mod.rs证明当字节流不是合法 PDF 时解析会返回XbergError::Parsing错误消息描述文件corrupt/invalid——即解析层的结构化失败最终被折叠为该输入的ExtractionErrorItem。五、测试验证端到端断言如何落地Java 端到端测试中该用例被固化在 e2e/java/src/test/java/io/xberg/e2e/BatchTest.java 的testExtractBatchUriPartialFailureString inputsMockBaseUrl System.getProperty(mockServer.extract_batch_uri_partial_failure, System.getenv().getOrDefault(MOCK_SERVER_EXTRACT_BATCH_URI_PARTIAL_FAILURE, System.getProperty(mockServerUrl, System.getenv(MOCK_SERVER_URL)) /fixtures/extract_batch_uri_partial_failure)); String inputsJson0 {\kind\:\uri\,\uri\:\$mock_url/text/plain.txt\}.replace($mock_url, inputsMockBaseUrl); String inputsJson1 {\kind\:\uri\,\uri\:\$mock_url/pdf/corrupt_truncated.pdf\}.replace($mock_url, inputsMockBaseUrl); var result Xberg.extractBatch(java.util.Arrays.asList(JsonUtil.fromJson(inputsJson0, ExtractInput.class), JsonUtil.fromJson(inputsJson1, ExtractInput.class)), ExtractionConfig.builder().build()); assertEquals(1, result.summary().results()); assertEquals(1, result.summary().errors());几个值得注意的工程细节Mock 服务器通过系统属性或环境变量mockServer.extract_batch_uri_partial_failure/MOCK_SERVER_...注入 base URL测试无需真实外网依赖CRAWLBERG_ALLOW_PRIVATE_NETWORKtrueBeforeAll中设置允许抓取组件访问本地 mock 服务见 BatchTest.java同时把RUST_MIN_STACK提到 16 MB 以满足深调用栈需求断言只落在summary上results 1、errors 1是这条用例的行为契约任何破坏部分失败折叠语义的改动都会让测试变红。BatchTest 中还覆盖了同一语义下的其他形态可作为对照BatchTest.java全失败testExtractBatchUriAllMissingresults 0, errors 2、单失败testExtractBatchUriNotFoundresults 0, errors 1、空批量testExtractBatchEmptyInputsresults 0以及 bytes 输入的错误 MIME 处理。六、生产实践正确消费批量结果综合上面的语义落地到生产代码时可以遵循四条准则先读 summary再决定是否遍历 results。summary().errors() 0不代表调用失败只代表部分输入失败先打印summary就能一眼看出批量健康度。遍历errors()做定向重试。ExtractionErrorItem.index()映射回输入列表下标source()给出原始 URIerror_type()/code()可用于区分网络失败、格式不支持、解析损坏等类别只对可重试类别做重试。区分信封异常与条目错误。extractBatch抛出的XbergRsException属于配置/FFI 级故障应当直接捕获并中止条目错误则永远在errors列表里不会冒泡。善用默认配置与按输入覆盖。ExtractionConfig.builder().build()即可开箱运行若批量内个别文档需要不同 OCR 或格式策略可通过ExtractInput的config字段做 per-input 覆盖引擎会按 resolve_input_config 的逻辑合并。七、延伸阅读用例定义与断言fixtures/batch/extract_batch_uri_partial_failure.jsonJava 门面 APIpackages/java/io/xberg/Xberg.java、packages/java/io/xberg/XbergRs.java结果信封模型packages/java/io/xberg/ExtractionResult.java、ExtractionSummary.java、ExtractionErrorItem.javaRust 引擎实现crates/xberg/src/engine/extract_impl.rs、crates/xberg/src/core/config/extraction/types.rsJava 批量处理入门示例packages/java/README.md端到端测试e2e/java/src/test/java/io/xberg/e2e/BatchTest.java赞分享后端AI 应用NLP【免费下载链接】xbergPolyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.项目地址https://gitcode.com/gh_mirrors/kr/xberg点击查看免费下载相关推荐xberg C API 批量提取实战extract_batch 的 URI 部分失败语义与容错设计xberg C API 批量提取实战extract_batch 的 URI 部分失败语义与容错设计 本篇技术指南以 xberg 官方 C API 测试夹具 e后端AI 应用NLPXberg Java 批处理提取实战extract_batch 处理缺失 URI 输入的容错机制与结果解析Xberg Java 批处理提取实战extract_batch 处理缺失 URI 输入的容错机制与结果解析 本指南以 Xberg 官方 Java 示例 ext后端AI 应用NLPXberg Dart 批量提取容错实战extract_batch 处理全部缺失 URI 输入Xberg Dart 批量提取容错实战extract_batch 处理全部缺失 URI 输入 导读 当一批待提取的文档 URI 全部指向不存在的文件如路径拼后端AI 应用NLP上一篇requirejs与Meteor集成全栈JavaScript应用的模块化开发下一篇TrajectoryCrafter环境配置完全指南从零搭建28GB GPU的完整流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表