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

Tell spork to reload #9

Closed
bmabey opened this issue Jul 31, 2009 · 9 comments
Closed

Tell spork to reload #9

bmabey opened this issue Jul 31, 2009 · 9 comments

Comments

@bmabey
Copy link
Contributor

bmabey commented Jul 31, 2009

It would be very helpful if you could programmatically tell spork to reload. My use case is within autotest. When certain files change the entire environment needs to be reloaded. I'd like to be able to tell spork to reload from within my autotest mapping hooks. This could be done by sending a signal to the spork process or maybe connecting to the DRB server.

@bmabey
Copy link
Contributor Author

bmabey commented Jul 31, 2009

Actually.. in addition to having all of spork reload what would be very cool is if we could send arbitrary code (via DRb) to the parent spork process that would be evaluated. That way, we could tell it only to reload certain parts that we know need to be reloaded. Just an idea.. reloading all of it is probably easier to do at this point.

@timcharper
Copy link
Contributor

This sounds very cool. In order to achieve the "reload specific portions of the app part" we would have to create a few layers of forked processes, similar to how passenger does it. I think having a full restart occur would be a great start and may suffice.

@stepheneb
Copy link
Contributor

I just sent a pull request to both of you with a rough initial reload implementation to take a look at.

This gist: http://gist.github.com/216680 shows how to use the kicker gem to send Drb spec_sever.reload requests when code files change in rails.

@stepheneb
Copy link
Contributor

Hmm ... I just found a much simpler work-around for at least one part of this problem.

Here's a simple description of what I'd like to do:

  • Have a rails model and the spec test for that model open in textmate
  • command-R in the spec test to see the results
  • change code in the model
  • command-R again in the spec test to see new results

We are using Factory girl and normally when we run this command to see what is loaded in prefork:

spork -d | grep -A25 models

I see FactoryGirl load all the model classes we are using factories for -- of course by doing that in prefork it means that any model changes I make after spork startup don't appear after the fork.

We added this file: config/initializers/spork.rb

if defined?(Spork)
  Spork.trap_class_method(Factory, :find_definitions)
end

reference, Tim's suggestion in this thread: http://groups.google.com/group/sporkgem/browse_thread/thread/24e6342e6629d371#

This delays FactoryGirls loading of the model classes it needs to introspect until after the fork.

My simple test above now works.

My test environment is setup to cache classes (config/environments./test.rb)

config.cache_classes = true

My vendored rails is 2.3.4.

I had thought the model classes would be eagerly loaded in this case but appears not to be the case.

Thinking about how to get the most performance using spork in testing -- obviously the first step is to use more mocks and less factories/fixtures ... but after that a useful generalization is:

  • load as many app classes and generate app/state in prefork as possible AND is necessary for your tests
  • don't load classes in prefork that you are working on (or app state that might be affected by the change in these classes)

It might be helpful if after Spork started I could add or subtract classes from prefork app state. My method above which reloads the whole prefork is just brute force. If I had kicker watching for fsevents and in the case above removed just the model class I was working on from the prefork -- that might help. I don't know how unloading the class would affect the app state if it already had instances using the earlier versions of the model ...?

@thibaudgg
Copy link

FYI, RSpactor (0.6.x) handle Spork reload like that: http://github.com/thibaudgg/rspactor/blob/v0.6/lib/rspactor/spork.rb

@timcharper
Copy link
Contributor

This looks rocking! I will have to investigate. Thanks for pointing it out!

@thibaudgg
Copy link

I'll certainly refactorize this spork.rb implementation for the 0.7.x version of RSpactor (using IO.popen), but for that I'm waiting for the Rails 3/RSpec 2 compatibility ;-)

@timcharper
Copy link
Contributor

sigh... it's been a long road. I spent several hours last week just refactoring to make all the tests run with bundler (which is totally awesome and will make it easy for anyone to run the tests). But, it's getting closer :) Closer as in if you're traveling from Spain to New York, you'd be in Portugal right now.

@thibaudgg
Copy link

Yeah, continue this great works! RSpactor 0.7 with RSpec 2 & Spork support will be super awesome!

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

No branches or pull requests

4 participants