mirror of
https://github.com/samuelncui/acp.git
synced 2026-11-08 12:27:05 +00:00
Reshape the public API around one push engine and restore theaf05f05csurface as a compatibility shell over it. - NewStream takes caller-owned items (Source/Targets), reports every accepted item through one results callback, and Wait returns the run's terminal error. Run, BatchSource and the item callbacks are gone. - The engine owns the result path: WithResultBuffer is the depth of the result queue, WithResultBatch is how many results one delivery carries, and WithResultFlushInterval is how long a successful result may wait. A result that carries any error is delivered immediately as its own batch. - Restore theaf05f05cAPI byte-compatibly in the same package: New, Copyer, Wait/WaitErr, AccurateJob, WildcardJob, the report events and the JSON report round-trip through encoding/json alone. - One descriptor serves a whole item; the stored hash is read through the descriptor that reads the content and the computed hash is published through it before it closes. - Make every handoff escapable by a hard stop: the read buffer, a chunk send, an event send and the result buffer. - Fix the recorded sweep findings: report indent and round-trip, cmd/acp exit status, acp-rewrite final paths, mmap EOF/close/slice, disk-usage reservations, ErrTargetIO identity, the fatal-panic safety net, option validation, and the FreeBSD/Windows build paths. - Cover the contract with semantic tests, add Makefile check/race/vet/cross targets, and document the withdrawn v0.1.0/v0.2.0 migration in README.
71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
package acp
|
|
|
|
import "fmt"
|
|
|
|
// ReadMode selects how a source device reads its content.
|
|
type ReadMode uint8
|
|
|
|
const (
|
|
// ReadBuffered reads through the kernel's buffered path, which is the default.
|
|
ReadBuffered ReadMode = iota
|
|
// ReadMapped reads through a memory mapping.
|
|
ReadMapped
|
|
)
|
|
|
|
func (m ReadMode) String() string {
|
|
switch m {
|
|
case ReadBuffered:
|
|
return "buffered"
|
|
case ReadMapped:
|
|
return "mapped"
|
|
}
|
|
return fmt.Sprintf("unknown(%d)", uint8(m))
|
|
}
|
|
|
|
type deviceOption struct {
|
|
linear bool
|
|
threads int
|
|
readMode ReadMode
|
|
}
|
|
|
|
func (do *deviceOption) check() error {
|
|
if do.threads < 0 {
|
|
return fmt.Errorf("device threads cannot be negative, threads=%d", do.threads)
|
|
}
|
|
if do.threads == 0 {
|
|
do.threads = 8
|
|
}
|
|
if do.linear {
|
|
do.threads = 1
|
|
}
|
|
if do.readMode != ReadBuffered && do.readMode != ReadMapped {
|
|
return fmt.Errorf("unknown read mode, mode= %s", do.readMode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type DeviceOption func(*deviceOption) *deviceOption
|
|
|
|
func LinearDevice(b bool) DeviceOption {
|
|
return func(d *deviceOption) *deviceOption {
|
|
d.linear = b
|
|
return d
|
|
}
|
|
}
|
|
|
|
func DeviceThreads(threads int) DeviceOption {
|
|
return func(d *deviceOption) *deviceOption {
|
|
d.threads = threads
|
|
return d
|
|
}
|
|
}
|
|
|
|
// WithReadMode selects how a source device reads its content. It applies to the source
|
|
// device only and defaults to buffered reads.
|
|
func WithReadMode(mode ReadMode) DeviceOption {
|
|
return func(d *deviceOption) *deviceOption {
|
|
d.readMode = mode
|
|
return d
|
|
}
|
|
}
|