feat: JFR events for open, HTTP range, segment decode/encode, chunk filtering and writer back-pressure

Đang mở
#601 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
55/100
Loại issue
Tính năng
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java
Lĩnh vực
backend, observability

Hướng nghiên cứu

Start by reading the reader and writer entry points named in the issue: VortexReader.open, VortexHttpReader.open, SerializedArrayDecoder.decode, ScanIterator, and VortexWriter. Add the JFR event classes and wire them into those paths as specified, then use the named tests to check event fields, filtering counts, and back-pressure duration. Done when the event tests pass and the reference guide, how-to guide, changelog, and module map are updated.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

enhancement

Goal

Emit JDK Flight Recorder events from the reader and writer, so a JFR recording shows where a read or write spends its time (file open/mapping, HTTP range fetches, per-segment decode/encode, chunk pruning, writer back-pressure) with no extra dependency and near-zero cost when recording is off.

Events

New package core/src/main/java/io/github/dfa1/vortex/core/jfr/ (with package-info.java). Each event is a public class extending jdk.jfr.Event, annotated @Name("io.github.dfa1.vortex.X"), @Label, @Category({"Vortex", …}), @Description and @StackTrace(false). Public fields get /// docs (doclint is all); byte sizes get @DataAmount.

Class Category Fields
FileOpenedEvent I/O source, fileSize, formatVersion, segmentCount
FileMappingEvent I/O file, size
HttpRangeEvent I/O source, offset (-1 = tail), length, status (0 = no response)
SegmentDecodedEvent Decode encoding, rowCount, segmentSize
ChunkFilterEvent Filter totalChunks, chunksPruned, chunksWithoutMatch, chunksReturned, rowsReturned
SegmentEncodedEvent Encode encoding, bufferCount, encodedSize
SegmentWaitEvent Pipeline segmentsInFlight

Reader wiring

Pattern: event.begin(), set fields, commit().

  • VortexReader.open(path, registry, layoutRegistry): FileOpened spans the whole open and is committed after parse; FileMapping wraps channel.map. A failed open emits no FileOpened.
  • VortexHttpReader.open(uri, registry, layoutRegistry, client): FileOpened begins before fetchTail and is committed after the reader is built.
    • New private sendRange(req, client, uri, offset, length) wraps client.send in try/finally and always commits HttpRange, with status = 0 on failure. fetchTail calls it with offset -1 and TAIL_SIZE.bytes(); fetchRange with from and to - from + 1.
    • New package-private static String describe(URI) returning scheme://host[:port] + raw path. It drops user info, query and fragment, because presigned URLs carry credentials. Used for every source field.
  • SerializedArrayDecoder.decode: begin at the top; after registry.decode(ctx) set encoding = node.encodingId().id(), rowCount, segmentSize = segLen, then commit. Covers both readers.
  • ScanIterator:
    • New counters chunksPruned, chunksWithoutMatch, chunksReturned.
    • In hasNext(), split canPruneChunk(...) || !selectMatchingRows(...) into two branches that each count, chunkIndex++; continue.
    • Increment chunksReturned in next().
    • close() calls emitChunkFilterEvent(), a no-op when filter == null || chunks == null.

Writer wiring (VortexWriter)

  • encodeSegment: begin at the top; before returning, if (event.shouldCommit()) fill encoding from result.rootNode().encodingId().id(), bufferCount, encodedSize, then commit. Failures emit nothing.
  • drainSegments: replace pending.poll().join() with a static awaitHead(head, pending.size() + 1). It joins directly if head.isDone(); otherwise begins a SegmentWaitEvent, joins in a try, commits in the finally.
  • No change to the writer's default behavior. (The default executor runs tasks on the caller, so SegmentWait never appears there.)

Tests

Given/When/Then throughout. For events committed on other threads, assert presence and field values, never exact counts.

  • core/src/test/.../core/testing/JfrRecorderTest.java: abstract base; a RecordingStream with setReuse(false) starts in @BeforeEach; offers awaitEvents() and events(name).
  • reader VortexReaderJfrTest (fixture primitives.vortex): FileOpened and FileMapping fields; a too-small file emits no FileOpened.
  • reader VortexHttpReaderJfrTest (mocked HttpClient): tail HttpRange (offset -1, status 206); source has no credentials or query; status 0 when send throws IOException.
  • writer JfrEventsTest (uses LegacyZoneMaps.OPTIONS, same package):
    • SegmentEncoded present with non-negative sizes (a vortex.sequence segment has 0 buffers).
    • Default executor: no SegmentWait.
    • Executor sleeping 200 ms before each task: SegmentWait duration > 50 ms and segmentsInFlight > 0.
    • Chunks 1..50, 51..100, 101..150 with eq(id, 75) → totals 3/2/0/1 and 1 row.
    • Single chunk {1, 100} with eq(id, 50) → 1/0/1/0 and 0 rows.
    • Unfiltered scan emits no ChunkFilter.

Docs (same commit)

  • docs/reference.md: "JFR events" section (event table) + TOC entry.
  • docs/how-to.md: "Find where a read or write spends its time (JFR)".
  • CHANGELOG.md: ## [Unreleased] → Added.
  • AGENTS.md: core.jfr line in the module map.

Verify

  • ./mvnw test -pl core,reader,writer -am
  • ./mvnw verify -DskipTests (Javadoc lint + checkstyle)
Ngôn ngữ chính
Java
Star
3
Fork
2
Merge trung bình
9 giờ 51 phút
Pull request đã merge (30 ngày)
127

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của dfa1/vortex-java

Tất cả issue của dfa1/vortex-java

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.