reduce allocations

This commit is contained in:
Ahrav Dutta
2024-04-24 19:44:32 -07:00
parent 120cad6db6
commit bb8e05b72e
5 changed files with 38 additions and 39 deletions
+1 -1
View File
@@ -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),
}
}
+29 -32
View File
@@ -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.")
}
}()
+1 -1
View File
@@ -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 {
+6 -4
View File
@@ -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)
+1 -1
View File
@@ -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),
}
}