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

Aperta
#601 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
55/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
java

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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)
Lingua principale
Java
Stelle
3
Fork
2
Merge medio
14h 59m
PR unite (30g)
137

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di dfa1/vortex-java

Tutte le issue di dfa1/vortex-java

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.