loader/cache.go
func (l *CachedByteCodeLoader) Load(key string) (bc *vm.ByteCode, err error) {
	defer func() {
		if bc != nil && err == nil && l.ShouldDumpByteCode() {
			fmt.Fprintf(os.Stderr, "%s\n", bc.String())
		}
	}()

	var source TemplateSource
	if l.CacheLevel > CacheNone {
		var entity *CacheEntity
		for _, cache := range l.Caches {
			entity, err = cache.Get(key)
			if err == nil {
				break
			}
		}

		if err == nil {
			if l.CacheLevel == CacheNoVerify {
				return entity.ByteCode, nil
			}

			t, err := entity.Source.LastModified()
			if err != nil {
				return nil, errors.Wrap(err, "failed to get last-modified from source")
			}

			if t.Before(entity.ByteCode.GeneratedOn) {
				return entity.ByteCode, nil
			}

			// ByteCode validation failed, but we can still re-use source
			source = entity.Source
		}
	}

	if source == nil {
		source, err = l.Fetcher.FetchTemplate(key)
		if err != nil {
			return nil, errors.Wrap(err, "failed to fetch template")
		}
	}

	rdr, err := source.Reader()
	if err != nil {
		return nil, errors.Wrap(err, "failed to get the reader")
	}

	bc, err = l.LoadReader(key, rdr)
	if err != nil {
		return nil, errors.Wrap(err, "failed to read byte code")
	}

	entity := &CacheEntity{bc, source}
	for _, cache := range l.Caches {
		cache.Set(key, entity)
	}

	return bc, nil
}
func (l *CachedByteCodeLoader) Load(key string) (bc *vm.ByteCode, err error) {
	defer func() {
		if bc != nil && err == nil && l.ShouldDumpByteCode() {
			fmt.Fprintf(os.Stderr, "%s\n", bc.String())
		}
	}()

	var source TemplateSource
	if l.CacheLevel > CacheNone {
		var entity *CacheEntity
		for _, cache := range l.Caches {
			entity, err = cache.Get(key)
			if err == nil {
				break
			}
		}

		if err == nil {
			if l.CacheLevel == CacheNoVerify {
				return entity.ByteCode, nil
			}

			t, err := entity.Source.LastModified()
			if err != nil {
				return nil, errors.Wrap(err, "failed to get last-modified from source")
			}

			if t.Before(entity.ByteCode.GeneratedOn) {
				return entity.ByteCode, nil
			}

			// ByteCode validation failed, but we can still re-use source
			source = entity.Source
		}
	}

	if source == nil {
		source, err = l.Fetcher.FetchTemplate(key)
		if err != nil {
			return nil, errors.Wrap(err, "failed to fetch template")
		}
	}

	rdr, err := source.Reader()
	if err != nil {
		return nil, errors.Wrap(err, "failed to get the reader")
	}

	bc, err = l.LoadReader(key, rdr)
	if err != nil {
		return nil, errors.Wrap(err, "failed to read byte code")
	}

	entity := &CacheEntity{bc, source}
	for _, cache := range l.Caches {
		cache.Set(key, entity)
	}

	return bc, nil
}
// Load loads the ByteCode for template specified by `key`, which, for this
// ByteCodeLoader, is the path to the template we want.
// If cached vm.ByteCode struct is found, it is loaded and its last modified
// time is compared against that of the template file. If the template is
// newer, it's compiled. Otherwise the cached version is used, saving us the
// time to parse and compile the template.