Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asset loading race condition causes unexpected panic #165

Open
ViRb3 opened this issue Feb 8, 2021 · 0 comments
Open

Asset loading race condition causes unexpected panic #165

ViRb3 opened this issue Feb 8, 2021 · 0 comments

Comments

@ViRb3
Copy link

ViRb3 commented Feb 8, 2021

I have a private project that uses go.rice. It works flawlessly on Windows, but on Linux, it fails with:

panic: could not locate box "assets"

It is compiled from the exact same source, on the same host (Windows 10), with the same Go toolchain (1.15). I started debugging go.rice, and noticed a very interesting race condition. I will simplify it below.

Intro

Recall the order in which Go initializes code: https://stackoverflow.com/questions/24790175/when-is-the-init-function-run

Say you have the following project:

rice-box.go

package main

import (
	"time"

	"github.com/GeertJohan/go.rice/embedded"
)

func init() {
    // ...
}

main.go

package main

import (
	rice "github.com/GeertJohan/go.rice"
	"log"
)

var box = rice.MustFindBox("assets")

func main() {
	log.Fatalln(box.String("message.txt"))
}

The issue

The first thing that will load is:

var box = rice.MustFindBox("assets")

Only then will rice-box.go be called, but by that time, the program will have panicked, because the assets box is not loaded. There are many additional ways this issue can be hit, including much less-trivial nested and multi-thread cases like in my private project.

Solution

The root of the problem is that the resource initialization is detached from the resource usage. Other projects such as binclude reference a variable in the generated file instead of global library functions in go-rice's case. You can reduce the amount of race cases in go-rice by making the resource initialize via a const/var instead of init() function, but ideally, a whole different approach should be employed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant