Mongoid.override_database in Sidekiq and simultaneous Rails requests - ruby-on-rails

I'm just wandering when can I safely use Mongoid.override_database.
If I use it inside Sidekiq worker is DB going to be changed only for the worked which has called the override_database method?
How about using it in standard Rails controller? Is there any situation where it shouldn't be used (where it could cause problems)?
At first I've used .with(database: 'xyz') when I needed to change the DB, but then I've found out that it doesn't work on relational fields...

Related

How can I get the Rails Application controller to run a function when the server starts up?

I am working on a feature to limit the number of pages a user can access in a day. My plan is to create a class variable in the ApplicationController which is instantiated on startup. One of the features I want though is for this value to be changed by an administrator without having to worry about changing the config file, hence the class variable.
How can I have rails call a function in the application controller when rails starts up?
You can't do it this way. You must operate on the presumption that your Rails application will consist of multiple independent processes with entirely arbitrary lifetimes, that is they may be spawned if needed and killed if they're idle at any time.
You're stuck having to persist this somewhere. A flat file can work if you're using a single server, but a database of some sort, SQL or otherwise, is also viable. For light loads, that is less than dozens of requests per second, SQL won't be a problem.

Use two neo4j databases in single rails app

I have two neo4j databases running on two different hosts. I connected my rails app to one of them while generating the app. Now I want to use other database as well with the app. How can I configure the app to connect to both the databases?
There’s not currently a good way to configure one Ruby process to use two sessions at the same time. If you are using Rails you can change the server by setting the NEO4J_URL environment variable. Otherwise you’d need to manage the session by setting Neo4j::ActiveBase.current_session or Neo4j::ActiveBase.on_establish_session (which will set the session for each new thread, which may be needed if you are running a multi-threaded process)
See: https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_base.rb
As Brian mentioned currently we cannot configure one Ruby process to use two sessions at the same time. We have to manage the session by setting Neo4j::ActiveBase.current_session (See: https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_base.rb)
The neo4j.yml sets the Neo4j::ActiveBase.current_session for you in the railtie. If you set Neo4j::ActiveBase.current_session after the app has started up it will override what was in the neo4j.yml. The current_session needs to be a Neo4j::Core::CypherSession object from the neo4j-core gem. (See the readme: https://github.com/neo4jrb/neo4j-core)
Also keep in mind, that currently neo4j does not support having different session for each model. So you might experience problem if, setting the session inside model. A better way would be to set session in the normal runtime of the app. You also might want to wrap the Neo4j::Core::CypherSession to get Query Proxy instead of Neo4j::Core objects. To this you have to specify wrap_level: :proc while declaring the adaptor. (Refer: https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/session_manager.rb#L14)
So in all, here is what you need to do
http_adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new('http://neo4j:7474',{wrap_level: :proc})
Neo4j::ActiveBase.current_session = Neo4j::Core::CypherSession.new(http_adaptor)
this will establish a wrapped session with the desired database in 'http://neo4j:7474'

Rails: writing a record asynchronously

in my Rails 5 RC1 app write some log entries into a DB table through an ActiveRecord model.
Writing this log entry takes a couple of milliseconds and delays the response for the end user.
I am searching for a mechanism how I can execute the log-writing into the "background" so it is not blocking/delaying the response (kind of "fire-and-forget"). Do you have some hints on how to do that?
I tried to wrap the respective part into
Thread.new { code }
But this even seems to further delay the response a few MS.
I appreciate any hint!
Thanks and regards
Try looking into messaging services like RabbitMQ for asynchronous transactions and activities. I use RabbitMQ in exactly the way you describe.
If you are using ActiveJob, you could use :async, which looks to be the default queue_adapter for ActiveJob. However, this doesn't persist jobs between restarts and is not really recommended for production.
See Rails 5 changed Active Job default adapter from Inline to Async.

Rails convention on adding database entries from outside source regularly

Say I have a running rails project, and now I need to add entries to its database from an outside source. This is to be done automatically once a day and can be reduced to loading data from a text file.
Now I'm wondering, what is the conventional way to do this in a Rails project? Do I create a controller method which runs once a day and how do I call it? Do I access the database from outside with something like the sequel gem?
I think it depends of your application restrictions and business requirements.
My opinion is that both ways are good.
But I'd prefer to connect directly to database of use some message queue, just to avoid HTTP, to decrease number of HTTP calls.

Are Thread.current[] values and class level attributes safe to use in rails?

I have a particular problem I'm trying to solve in a rails 3 app, and the two common solutions that I'm seeing are these:
Thread.current[:something] = value
and
class Foo
cattr_accessor :bar
end
Foo.bar = value
Are these methods of data storage (and the corresponding retrieval) safe across multiple users making a request to my rails app, at the same time?
I'm concerned about Thread.current, because a web server could use a single thread to serve up multiple requests, right? Or is there something in the way rails handles threads to prevent problems when using Thread.current? I see Acts As Current uses Thread.current to store the current user, so that gives me hope... but I want authoritative confirmation.
I'm also concerned about class level attributes in a production environment, because I would expect rails to cache class objects in memory, for performance reasons. Does a class level attribute get re-used across requests? or is it safe due to something that rails does to handle class attributes across requests? again, i would like authoritative confirmation of this.
... this app uses Ruby 1.9.2#p180, with Rails 3.0.9
Safe enough to store the time zone of the current request:
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/zones.rb

Resources