edc / bass

Make Bash utilities usable in Fish shell
MIT License
2.18k stars 69 forks source link

Sourcing large number of exports is very slow, or hangs indefinitely #77

Open OJFord opened 4 years ago

OJFord commented 4 years ago

For example, with this large (2126 LoC at time of writing) $file: https://github.com/ryanoasis/nerd-fonts/blob/master/bin/scripts/lib/i_material.sh

bass -- set -o allexport \; "$file"

hangs longer than I care to wait - certainly non-linearly longer than this $file , which is only about 3/8 the size and takes <200ms: https://github.com/ryanoasis/nerd-fonts/blob/master/bin/scripts/lib/i_fa.sh

edc commented 4 years ago

Unfortunately, this is a side effect of Bass recently moving from using a temp file to using FIFO pipe for reading all environment variables. On MacOS, the pipe buffer is 16k and it is not changeable from Python. On Linux, this might be fixable by setting F_SETPIPE_SZ with fcntl but I did not try it. I suggest to just break the file apart?

OJFord commented 4 years ago

I see, thanks.

I suggest to just break the file apart?

That's not really ideal when, as is the case here, it's a third party file. In this case it might be safe since each line should always be independent - but the one I actual want to source is i_all.sh which is a loop through files in its directory, so that won't work (and as a result it's a small file anyway).

OJFord commented 4 years ago

@edc Could we perhaps have a flag to say --use-temp-file in cases where this can be anticipated?

edc commented 4 years ago

I don't have plan to implement that in the short to medium term, especially because Bass does not really parse flags properly. But I definitely welcome patches.

OJFord commented 4 years ago

No problem, thanks; it is a recurring itch for me, so I may get around to scratching it.

moving from using a temp file to using FIFO pipe for reading all environment variables

For my own reference, this change was in #33.

popbones commented 4 years ago

I think I have the same issue. We have a shell script which we need to source for a project. It includes a lot of large environment variables. Whenever I do bass source env.sh it hangs. Or at least it takes very long.

I've been using this https://github.com/edc/bass/pull/83 to mitigate the issue. I haven't touch Python for a while and I didn't dive into hunting down the root cause. But do have a look and see if this fixes the problem.

edc commented 4 years ago

I merged #83. Thanks for the fix!

OJFord commented 4 years ago

Thanks! I'll certainly give that a go, and close if that resolves mine too. Cheers.

edc commented 4 years ago

@OJFord This is good to close?

OJFord commented 4 years ago

@edc Sorry for the delay.

Snappy:

fish$ bass -- source large_file.sh
bash$ set -o allexport ; source large_file.sh
bash$ eval 'set -o allexport \; source large_file.sh'

Hangs:

fish$ bass -- set -o allexport \; source large_file.sh