reduce allocations
This commit is contained in:
@@ -22,7 +22,7 @@ type arHandler struct {
|
||||
// newARHandler creates an arHandler with the provided metrics.
|
||||
func newARHandler() *arHandler {
|
||||
return &arHandler{
|
||||
defaultHandler: newDefaultHandler(arHandlerType),
|
||||
defaultHandler: newDefaultHandler(arHandlerType, false),
|
||||
metrics: newHandlerMetrics(arHandlerType),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,15 +42,18 @@ func SetArchiveMaxTimeout(timeout time.Duration) { maxTimeout = timeout }
|
||||
// defaultHandler provides a base implementation for file handlers, encapsulating common behaviors
|
||||
// needed across different handlers. This handler is embedded in other specialized handlers to ensure
|
||||
// consistent application of these common behaviors and to simplify the extension of handler functionalities.
|
||||
type defaultHandler struct{ metrics *metrics }
|
||||
type defaultHandler struct {
|
||||
isArchive bool
|
||||
metrics *metrics
|
||||
}
|
||||
|
||||
// newDefaultHandler creates a defaultHandler with metrics configured based on the provided handlerType.
|
||||
// The handlerType parameter is used to initialize the metrics instance with the appropriate handler type,
|
||||
// ensuring that the metrics recorded within the defaultHandler methods are correctly attributed to the
|
||||
// specific handler that invoked them. This allows for accurate metrics attribution when the defaultHandler
|
||||
// is embedded in specialized handlers like arHandler or rpmHandler.
|
||||
func newDefaultHandler(handlerType handlerType) *defaultHandler {
|
||||
return &defaultHandler{metrics: newHandlerMetrics(handlerType)}
|
||||
func newDefaultHandler(handlerType handlerType, isArchive bool) *defaultHandler {
|
||||
return &defaultHandler{metrics: newHandlerMetrics(handlerType), isArchive: isArchive}
|
||||
}
|
||||
|
||||
// HandleFile processes the input as either an archive or non-archive based on its content,
|
||||
@@ -61,39 +64,33 @@ func (h *defaultHandler) HandleFile(ctx logContext.Context, input readSeekCloser
|
||||
// Shared channel for both archive and non-archive content.
|
||||
dataChan := make(chan []byte, defaultBufferSize)
|
||||
|
||||
_, arReader, err := archiver.Identify("", input)
|
||||
if err != nil {
|
||||
if errors.Is(err, archiver.ErrNoMatch) {
|
||||
// Not an archive, handle as non-archive content in a separate goroutine.
|
||||
ctx.Logger().V(3).Info("File not recognized as an archive, handling as non-archive content.")
|
||||
go func() {
|
||||
defer close(dataChan)
|
||||
if !h.isArchive {
|
||||
// Not an archive, handle as non-archive content in a separate goroutine.
|
||||
ctx.Logger().V(3).Info("File not recognized as an archive, handling as non-archive content.")
|
||||
go func() {
|
||||
defer close(dataChan)
|
||||
|
||||
// Update the metrics for the file processing.
|
||||
var err error
|
||||
defer func(start time.Time) {
|
||||
if err != nil {
|
||||
h.metrics.incErrors()
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
h.metrics.incFileProcessingTimeouts()
|
||||
}
|
||||
return
|
||||
// Update the metrics for the file processing.
|
||||
var err error
|
||||
defer func(start time.Time) {
|
||||
if err != nil {
|
||||
h.metrics.incErrors()
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
h.metrics.incFileProcessingTimeouts()
|
||||
}
|
||||
|
||||
h.metrics.observeHandleFileLatency(time.Since(start).Milliseconds())
|
||||
h.metrics.incFilesProcessed()
|
||||
}(time.Now())
|
||||
|
||||
if err = h.handleNonArchiveContent(ctx, arReader, dataChan); err != nil {
|
||||
ctx.Logger().Error(err, "error handling non-archive content.")
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
return dataChan, nil
|
||||
}
|
||||
h.metrics.observeHandleFileLatency(time.Since(start).Milliseconds())
|
||||
h.metrics.incFilesProcessed()
|
||||
}(time.Now())
|
||||
|
||||
h.metrics.incErrors()
|
||||
return nil, err
|
||||
if err = h.handleNonArchiveContent(ctx, input, dataChan); err != nil {
|
||||
ctx.Logger().Error(err, "error handling non-archive content.")
|
||||
}
|
||||
}()
|
||||
|
||||
return dataChan, nil
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -115,7 +112,7 @@ func (h *defaultHandler) HandleFile(ctx logContext.Context, input readSeekCloser
|
||||
h.metrics.observeHandleFileLatency(time.Since(start).Milliseconds())
|
||||
}(time.Now())
|
||||
|
||||
if err = h.openArchive(ctx, 0, arReader, dataChan); err != nil {
|
||||
if err = h.openArchive(ctx, 0, input, dataChan); err != nil {
|
||||
ctx.Logger().Error(err, "error unarchiving chunk.")
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -83,7 +83,7 @@ func TestArchiveHandler(t *testing.T) {
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
defer resp.Body.Close()
|
||||
|
||||
handler := newDefaultHandler(defaultHandlerType)
|
||||
handler := newDefaultHandler(defaultHandlerType, true)
|
||||
|
||||
newReader, err := diskbufferreader.New(resp.Body)
|
||||
if err != nil {
|
||||
|
||||
@@ -126,7 +126,7 @@ var knownArchiveMimeTypes = map[mimeType]bool{
|
||||
// a defaultHandler is used, leveraging the archiver library to manage these formats.
|
||||
// The chosen handler is then configured with provided options, adapting it to specific operational needs.
|
||||
// Returns the configured handler.
|
||||
func getHandlerForType(mimeT mimeType) FileHandler {
|
||||
func getHandlerForType(mimeT mimeType, isArchive bool) FileHandler {
|
||||
var handler FileHandler
|
||||
switch mimeT {
|
||||
case arMime, unixArMime, debMime:
|
||||
@@ -134,7 +134,7 @@ func getHandlerForType(mimeT mimeType) FileHandler {
|
||||
case rpmMime, cpioMime:
|
||||
handler = newRPMHandler()
|
||||
default:
|
||||
handler = newDefaultHandler(defaultHandlerType)
|
||||
handler = newDefaultHandler(defaultHandlerType, isArchive)
|
||||
}
|
||||
|
||||
return handler
|
||||
@@ -177,12 +177,14 @@ func HandleFile(
|
||||
}
|
||||
|
||||
config := newFileHandlingConfig(options...)
|
||||
if config.skipArchives && knownArchiveMimeTypes[mime] {
|
||||
|
||||
isArchive := knownArchiveMimeTypes[mime]
|
||||
if config.skipArchives && isArchive {
|
||||
ctx.Logger().V(5).Info("skipping archive file", "mime", mimeT.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
handler := getHandlerForType(mime)
|
||||
handler := getHandlerForType(mime, isArchive)
|
||||
archiveChan, err := handler.HandleFile(ctx, rdr) // Delegate to the specific handler to process the file.
|
||||
if err != nil {
|
||||
return fmt.Errorf("error handling file: %w", err)
|
||||
|
||||
@@ -22,7 +22,7 @@ type rpmHandler struct {
|
||||
// newRPMHandler creates an rpmHandler with the provided metrics.
|
||||
func newRPMHandler() *rpmHandler {
|
||||
return &rpmHandler{
|
||||
defaultHandler: newDefaultHandler(rpmHandlerType),
|
||||
defaultHandler: newDefaultHandler(rpmHandlerType, false),
|
||||
metrics: newHandlerMetrics(rpmHandlerType),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user