inscapist / bundix

Generates a Nix expression for your Bundler-managed application. [maintainer=@inscapist]
9 stars 9 forks source link

Ideas to improve performance? #17

Open nyghtly-derek opened 2 months ago

nyghtly-derek commented 2 months ago

This seems to be the most active fork of bundix, so I'm placing my issue here.

I've been using the community fork of bundix at work and it's become a performance bottle neck for us when upgrading ruby gems.

As such, I'm curious if you've had any ideas so far to improve the performance of bundix? If so, then I might be able to allocate some work time on trying to implement those.

Hopefully you can point me in the right direction. Thank you!

inscapist commented 2 months ago

Hey @nyghtly-derek you are welcome to!

I think most of the time spent is in downloading the gems, which you can find in source.rb called by bundix.rb at the top level.

Do you know about async ruby? Converting the http calls to async should be a good starting point.

The code should be ruby 3 ready at this point. But you might need to bump up the ruby versions - in the gemspecs for example.

It may be useful to profile this area of the code as well

nyghtly-derek commented 2 months ago

Thank you @inscapist! These are some great leads. I'll try out your suggestions.

Regarding the downloads, I'm curious if you're aware of any existing caching behavior? Or do we have to download fresh every time we call bundix? Not sure if caching would be a good idea or not, just thought I'd ask.

inscapist commented 2 months ago

there are two levels of caching here. If a gem has been downloaded previously, it will be reused, you can look at nix_prefetch_url to see the behavior.

The other level is the reuse of already computed gem hashes.

nyghtly-derek commented 2 months ago

Wow, this is already far superior to the other version of bundix available in nix packages! That one has to re-do all gems on every call. It also requires duplicate requests for gems that aren't platform-specific. Excellent work on this, it's a big improvement. Old news to you, I'm sure.

Anyways, I'm realizing now that async requests may or may not have a significant impact. I believe that I'm hitting a rate limit when downloading ruby gems, and that's the root cause of my slow worflow. Assuming that sending those requests async won't have an impact on how quickly the responses come back. But it would still be a modest improvement if you're only downloading a batch of 10-20 at once.

inscapist commented 2 months ago

I believe that I'm hitting a rate limit when downloading ruby gems, and that's the root cause of my slow worflow

Were there errors that mention the rate limits in particular? iirc, gems themselves are served by the CDN and it would be hard to hit the limit. The rate limit that I had to work with was from the dependency API, with a cap of 15 req/s.

But I do agree that the efforts may not outweigh the benefits

nyghtly-derek commented 2 months ago

Hm, that is interesting. I didn't see any explicit errors. But I did notice that it started off very fast, with each gem taking about 0.1 second, then it slowed down with each gem taking a few seconds. I didn't see any resource bottle necks on my machine, so I assumed it was network-related. That's for a batch of about 200 gems.

inscapist commented 2 months ago

I see