func()

in internal/vfs/zip/archive.go [74:108]


func (a *zipArchive) openArchive(parentCtx context.Context, url string) (err error) {
	// always try to update URL on resource
	if a.resource != nil {
		a.resource.SetURL(url)
	}

	// return early if openArchive was done already in a concurrent request
	if status, err := a.openStatus(); status != archiveOpening {
		return err
	}

	ctx, cancel := context.WithTimeout(parentCtx, a.openTimeout)
	defer cancel()

	a.once.Do(func() {
		// read archive once in its own routine with its own timeout
		// if parentCtx is canceled, readArchive will continue regardless and will be cached in memory
		go a.readArchive(url)
	})

	// wait for readArchive to be done or return if the parent context is canceled
	select {
	case <-a.done:
		return a.err
	case <-ctx.Done():
		err := ctx.Err()
		if errors.Is(err, context.Canceled) {
			log.ContextLogger(parentCtx).WithError(err).Traceln("open zip archive request canceled")
		} else if errors.Is(err, context.DeadlineExceeded) {
			log.ContextLogger(parentCtx).WithError(err).Traceln("open zip archive timed out")
		}

		return err
	}
}