Closed mecha1 closed 9 years ago
@mecha1 thanks for digging into this.
The :init
option allowed us to preload garden in the pod pool shaving of a few seconds for each build cycle. Ideally I would like to keep this behaviour. Have you been able to find the root cause for the exception you were getting in #7?
@martinklepsch I'm not clear on how you are expecting :init to shave a few seconds off the build cycle, but from your comment it sounds like you want the init function to be called only once for any number of invocations of the garden task. This is not what is happening. Each time the boot garden task is called, it calls (garden-pool). This means that if you call the boot garden task twice and the :init option is retained, it will call that :init function twice. The exception occurs on the second call to the :init function.
@mecha1 Every time the garden
task compiles your stylesheets it uses a new pod from the pod pool. This pod needs to require garden.core
itself and your stylesheet var's namespace. The latter is only done after ns-tracker
told us that the namespace has changed. In comparison to your stylesheet namespace the garden.core
namespace is static and thus we can load it as soon as we create a pod in the pool. That's what :init
is for. It allows you to specify something that should be run as soon as the pod is ready and before you actually take it from the pod pool using refresh
.
For details see the pod-pool
docstring.
Have you not observed any differences in cycle times?
@martinklepsch I think there is a discrepancy with the way we are expecting :init
to work and the way it is actually working. If you place a print statement in the :init
function you will see that the :init
function is called when each pod in the pool is first created, AND on every subsequent time you call refresh
to take a pod from the pool.
I was originally expecting that the :init
function would be called once on pod creation and not afterwards on subsequent pod access, but this is not what is happening. The end result is that instead of saving time by not having to invoke the :init
function again whenever accessing a pod from the pool, we are actually wasting more time by using :init
than if we didn't use it at all. This feels like a bug in boot (I'm using Boot 2.2.0 by the way). Let me know what you think.
The other issue is that if you are doing two invocations of the boot-garden
task, e.g.:
boot watch garden -s mecha1.www.styles/s1 -o s1.css -- garden -s mecha1.www.styles/s2 -o s2.css
it will create the pods and call the :init
function on them concurrently, which then causes the exception in #7. I'm still not sure why this is, but it is. If you add a (Thread/sleep 5000)
into your :init
function it will circumvent this issue, but this is obviously not ideal. It seems preferable to remove the :init
option entirely, especially given the aforementioned behavior of the :init
function being called too many times.
@martinklepsch hmm, ok maybe it was only my misunderstanding. I was expecting boot to reuse pods in the pool, but that is not what it does. It initializes pods (using :init
) and then discards them after they are used. So it looks like boot is behaving as expected.
The issue with boot-garden then looks like that it is creating a new pod-pool for each invocation of the garden task. I changed this to a single global garden pod pool and can now avoid the exception in #7 while still keeping the :init
functionality. I have updated the pull request accordingly with the new changes.
This makes perfect sense. Thank you.
Would you still consider the exception to be a problem with Boot? If you feel like it a minimal repro would be awesome to file a bug against Boot so we can fix it there :) Seems like the base problem is creating two pod pools with two invocations of the same task.
Ok, I'll put something together.
Another thing I noticed is that the using :take
instead of :refresh
to acquire pod instances from the pool is substantially faster, because :refresh
first synchronously calls destroy
to clean up the existing pod before returning a new pod instance. It might be a nice feature to have boot return the new pod instance first and then asynchronously destroy the old instance as a performance enhancement.
…oved :init fn from garden pool