I have some iPhone client tests that run against my development rails server. The whole suite runs an order of magnitude faster if I turn on class caching in the Rails config. On the other hand, that slows down development when I'm not actually running the tests.
I want the test suite to hit an action at the beginning to turn on class caching and another action at the end to turn class caching off again.
Is this even possible? If so, how?
Not without some serious hacking. Rails goes to quite a lot of trouble to make sure your files are reloaded on every request (when cache_classes=false). The value of the cache_classes configuration variable is used by initializers in several places not the least of which being:
using require to load ruby files when cache_classes is true (meaning they are no longer reloadable)
setting up dispatcher callbacks to reaload the application on every request when cache_classes is false
You do have access to the value of the cache_classes variable, and you can even change it if you like:
Rails.configuration.cache_classes = true
But, this will have no effect on the running rails instance as the initializers where that value is used only run once when the rails app starts up.
What this means is this, unless you're prepared to invest some serious time and hacking effort you can't really avoid a restart of your server. So, what you need to look at is controlling this restart process via your test suite.
For example you can try to restart rails from within rails. This would allow you to define an action that your test suite can hit right before it begins executing (to restart the server in the right mode), and another action which the server can hit after all tests have finished, to restart everything with cache_classes set to what it used to be. You would control the value of cache classes via an environment variable like this post suggests.
It would still require a bit of work to set all of this up and get it to hang together, but this is probably your best bet if you want an 'auto-magical' solution.
I don't think doing what you suggest will work.
But I suggest you may be looking for the wrong solution.
If what you want is to access your development database from your iphone testing,
then why not add a new environment.
Add a new file config/environments/iphone_dev.rb
require File.dirname(__FILE__)+"/development.rb"
config.cache_classes = true
And in your database.yml (or mongoid.yml or whatever)
iphone_dev:
host: localhost
database: my_app_development
There is no reason the database cant be the same
Now just run rails server -eiphone_dev -p3001
You should have a server, almost the same as your dev server,
but running on a different port, with caching enabled.
Related
I was hoping to put in some sanity checks on Rails (v5) application startup to ensure that all necessary ENV variables / configuration was properly set.
However, I want to run these checks only if I'm actually running the server. I don't want it happening any time the Rails environment is loaded, e.g., running tests, asset precompilation (including with RAILS_ENV=production), rails c, etc.
Is there a place in the Rails start-up chain that I could insert those sanity checks without affecting all Rails-related tasks?
This is an interesting challenge. The problem is that (virtually) the entire application is loaded regardless of whether you're running tests, pre-compiling assets or anything else. The only thing that's different is that you have the process residing in memory.
Have you considered creating a production validation task that you run in your deployment process prior to launching the server process?
EDIT : Additional Thoughts
Looking at the rails server command, it calls an instance of Rails::Server, a subclass of Rack::Server (whereas rails console calls an instance of Rails::Console).
You have two choices:
Task (Best Choice)
Create a rake task that you execute during your deployment process prior to starting the server process. It should raise an error if the configuration is not valid, which should halt your deployment process.
I strongly suggest this approach. It's self-contained, you can test it far easier, and you don't have to meddle with the internals of the server process.
Monkey Patch Rails::Server#start
Monkey patch Rails::Server (probably Server#start) so it runs your validation logic if it's running in a production environment. If it doesn't, throw an error. This is ugly, you won't be able to test it easily, and it violates my sense of order :P
I know you don't want this logic to run in production environment in non-server use cases but my production deployments are always configured completely regardless of what I do with them. I've been debating setting up a validation step myself.
At work, we have a situation where when
script/server
is run, then all the controller code is cached. This is to speed up the
development server. But that will mean that whenever we change the
controller code, we need to restart the server.
So we can turn off the caching of controller code all together. But
can't there be mechanism that is similar to the inclusion of javascript
foo.js?1275647624 <--- UNIX timestamp
which is to use the cached version as long as there is no code change,
but recompile it when there is code change?
Maybe because we use HAML and SASS a lot, loading some page (such as the
homepage of the site) can take 40 seconds on the dev environment and it
is quite long.
By default Rails will reload your classes for every request in the development environment. This should ensure that any changes are picked up. Classes are usually only cached when running in the production environment, or possibly if you have a staging environment set up.
Obviously I don't know your application, but 40 seconds to load a home page in development sounds like a long time. Are there any errors in the log?
I am working on an existing Rails 2.3.x application, So I was working on it and it was a messy code with great difficulty I was able to run the application. But now for every small change in one of my controller it is expecting me to restart my serer otherwise the changes are not reflecting back, Let's take an example scenario here, Let's just say in one of the before_filter method I just added a puts statement on top of the method and it was not printing in the log, after I restart the server it is printing, Can some one please let me know if I am missing something here.
What environment are you using?
The default environment is 'development', where the code is reloaded on each request. However, this behaviour can be overwritten in the config file.
To be sure that the code is reloaded, add this into your config/development.rb file:
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false
If you are using config.threadsafe! It needs to be present before config.cache_classes=false as threadsafe makes cache_classes true again, following link would make it more clear. here
Maybe you have don't flush. The log system in Rails use a BufferedLogger. So need a flush to be print. Try a default logger.
What are the difference between three modes in rails like:-
In development mode, Rails reloads models each time a browser sends in a request,
so the model will always reflect the current database schema.
EDIT
I was asking about the other differences. I mentioned one i was looking for other list of differences...!!
It comes down to performance and stability. In production mode, model are cached in memory, meaning that once they have been read once, the files don't have to be read again, bringing an obvious speed benefit. This means that if you were to alter the ruby file (eg app/models/page.rb) where a model is defined, this change would not be picked up until the next reload.
By default, the following line is found in config/environments/production.rb:
config.cache_classes = true
The assumption is that when you're in production mode, you won't be changing your code other than via a release or deployment. If you want to clear the cache, you need to restart the application.
The development environment will reload your models each time it receives a request. This is controlled by the following default line in config/environments/development.rb:
config.cache_classes = false
In terms of the 'third' mode, I presume you mean test mode. This also caches models by default (see config/environments/test.rb), again with the assumption that you won't be altering your codebase mid-way through a test run.
Btw, it's not just models - I'm pretty sure that this setting encompasses any classes found within the 'app' directory. In addition, you will find that, even in development mode, classes located elsewhere in the application (eg 'lib') can not be changed without restarting the application.
The behavior of the three modes is configured in:
rails_app/config/environments/[production|development|test].rb
So, it depends on your configuration how the three modes are different.
I'm new to Ruby on Rails and am creating a test application. So far, it's working, but when I make some minor changes to my views, the page doesn't change.
My problem may be related to this question, but I'm not sure what is meant by setting the date and time in the VM. My code is on a remotely hosted server, so I assume it would use the system time of that machine.
Is there a caching issue here? What can I do about it?
If you don't have control over the server environment yourself (no shell access, etc.), you can set the following at the top of config/environment.rb:
ENV['RAILS_ENV'] = 'development'
Development doesn't cache much, so while it's slower it's much nicer to develop in.
You'll still need to restart your app after making changes to anything outside the app/ folder though (configs, plugins, etc.).
You need to restart your Rails app (or Apache if you are using Passenger) if you are in production mode!