Will "system()" call in Ruby wait until it finishes? - ruby-on-rails

I'm new to ruby on rails. I want to call a system command to analyze an uploaded file in my Rails application. Something as follows:
after_save :analyse #post processing call
def analyse
command = "./c_executable " + Rails.root.to_s + "/output_csv_file"
system(command)
if FileTest.exists?(Rails.root.to_s + "/output_csv_file")
parse_csv
end
end
It runs fine on my local machine, but for some reason the function "parse_csv" won't get called on the server(dreamhost). However, I manually call the c_executable system command on the server and it outputs the csv file without a problem. Could anyone tell me what might be causing the problem here? I was thinking the system call takes some time to finish on the server. If that's the case, I'm wondering if there is a way to tell rails to wait until the system() call finishes execution. Thanks in advance!

The system call should block until the command inside is finished. It is possible that the file is not being created as you intended which might preclude that part of your app from running.
You might want to use a different way of constructing your path to be sure you're getting it right:
csv_path = File.expand_path('output_csv_file', Rails.root)
unless (system('./c_executable', csv_path))
# Could't execute system command for some reason.
end
if (File.exists?(csv_path))
# ...
end
When making system calls it's generally a good idea to specify the full path to the executable as your application PATH may be different from what you expect.

My first guess is that it's a permissions error. Do you know what user the web/app server is running as and see if it has the correct permissions to both read/execute the command and write the output file.

I'll answer my own question now. After spending several days of testing and googling, it turns out that dreamhost doesn't allow these kind of non built-in system calls. I'll have to change my hosting service.

Related

Discrepancies when executing a command in Rails controller vs Rails console

I am trying to run the df command to display statistics of the disks which are attached to my server. However, it always returns the size of the disk as 0. If I run the same command in the rails console within the production environment, it returns the size of the disk.
Here's how my code is structured,
class Disk
def self.metrics
`df -h`
end
end
And this is how I call it in the controller,
class DiskController
def metrics
#metrics = Disk.metrics
end
end
But it always returns nil when I try to see the result in the view. The same command however works in the Rails console.
I've tried using system, POPEN but everything returns the same result.
Also, the same thing works in development (Mac OSX) but not in production (Linux Ubuntu).
Your console is running under the user you have logged in. Your Rails app is running under the user, dedicated to run your web server. I believe call to whoami from within the controller code will show the user name. This user is likely to be restricted to run df command. Though this is not recommended, the possible solution would be to grant this user to execute df command (via /etc/sudoers.)
I would go with another approach, though. I would add a cron job, that will execute df -h on behalf of any permitted user and put the output inside some text file within your project tree. The controller might then read this file to show the disk usage info.
I understand that the information might be slightly obsolete, but since one might execute the cron job each, say, minute, it should be acceptable. The advantage of this approach would be that web server still won’t have an access to system commands.

Rails Runner hanging with specific job

I have a Rails project and I am trying to run a script using Rails runner. This script runs fine on my local machine, but I am trying to run it on a new EC2 instance that I just set up.
When I run the script, it exhibits some very odd behavior. The first line in the script is a debug statement "Starting". When I say "hang" I mean that "Starting" is never printed.
rails runner Script.run //hangs forever
It is worth mentioning that the purpose of this script is to make several HTTP requests. So, in debugging it, I commented out various lines until I had the maximal program that would actually run.
The only line I needed to comment out is the one that actually called Net::HTTP.request. Then, the script would run, and print all of the debug statements that it was supposed to, but it wouldn't actually function as intended (obviously).
What seems odd to me is that the script will not even print "Starting" when the line that makes the HTTP request is present. The error would make some sense if it got to the HTTP request itself and then hung forever, or at least got some part of the way into the program.
What can cause Rails to behave this way? Any suggestions are appreciated.
Thanks!
I actually made a dumb mistake, but I am going to answer my question for anyone who makes the same mistake in the future.
I forgot to add "$stdout.sync = true" to the config file, so Rails just appeared to be hanging because it was not writing to stdout. When the HTTP request was disabled, it ran fast enough so that I didn't notice the writing was delayed.

Ruby on Rails: Executing JAR

Folks, i'm trying to execute a jar file inside RoR. Thanks to SO, I figured using IO::popen calls to execute a jar file.
Requirements:
- To login to site: To let our company employees login. Its a Java library which does some magic and figures if the username/password is valid. Which I did using,
result = IO::popen("java -cp auth.jar com.name.auth.LDAPLookup " + params[:username] + " " + params[:password]).read
p result
output: ["Authorized", "email", "id"]
No input sanitizing done. This is risky. Anyone could type something up in username/password and that will be executed in the server.
I'm not sure how to do this. One option I want to try is to use fork() or Process APIs to launch "java" and pass arguments. Couldn't figure out however. Any other thoughts?
Aside from the issue you mention, this sounds pretty painful in terms of performance (you're waiting around for the JVM to start up on every request, after all).
Two solutions jump out at me:
Look what the library does, and see if you really need to call out to Java for this; in particular, if it's just a question of making a lookup in an LDAP directory with a set of canned parameters, there are plenty of gems for that
If you must make use of Java classes from Ruby, strongly consider using JRuby, which will let you call the Java class in question directly, with neither the overhead of restarting the JVM on each call, nor the risk which comes with trying to correctly escape your arguments from Ruby to the shell to the JVM, and back.

What is the best way to get pass this common Solr error?

This error comes up if my computer has been on for awhile, and I've been toggling between different applications.
Normally if I perform sunspot-solr stop and sunspot-solr start, that is all that is required to get my server up and running happily.
But if the conditions I mentioned occured, then I get this :
Solr Response: Severe_errors_in_solr_configuration__Check_your_log_files_for_more_detailed_information_on_what_may_be_wrong__If_you_want_solr_to_continue_after_configuration_errors_change____abortOnConfigurationErrorfalseabortOnConfigurationError__in_null___javalangRuntimeException_javaioFileNotFoundException_no_segments_file_found_in_orgapachelucenestoreNIOFSDirectoryprivatevarfoldersDHDHXHq79mEpqXT6vQyzkhaETITmpindex_files_lucene0df3ec9bbc1f2dea7d43b32c37464540writelock__at_orgapachesolrcoreSolrCoregetSearcherSolrCorejava1068__at_orgapachesolrcoreSolrCoreinitSolrCorejava579__at_orgapachesolrcoreCoreContainer$InitializerinitializeCoreContainerjava137__at_orgapachesolrservletSolrDispatchFilterinitSolrDispatchFilterjava83__at_orgmortbayjettyservletFilterHolderdoStartFilterHolderjava99__at_orgmortbaycomponentAbstractLifeCyclestartAbstractLifeCyclejava40__at_orgmortbayjettyservletServletHandlerinitializeServletHandlerjava594__at_orgmortbayjettyservletContextstartContextContextjava139__at_orgmortbayjettywebappWebAppContextstartContextWebAppContextjava1218__at_orgmortbayjettyhandlerContextHandlerdoStartContextHandlerjava500__at_orgmortbayjettywebappWebAppContextdoStartWebAppContextjava448__at_orgmortbaycomponentAbstractLifeCyclestartAbstractLifeCyclejava40__at_orgmortbayjettyhandlerHandlerCollectiondoStartHandlerCollectionjava147__at_orgmortbayjettyhandlerContextHandlerCollectiondoStartContextHandlerCollectionjava161__at_orgmortbaycomponentAbstractLifeCyclestartAbstractLifeCyclejava40__at_orgmortbayjettyhandlerHandlerCollectiondoStartHandlerCollectionjava147__at_orgmortbaycomponentAbstractLifeCyclestartAbstractLifeCyclejava40__at_orgmortbayjettyhandlerHandlerWrapperdoStartHandlerWrapperjava117__at_orgmortbayjettyServerdoStartServerjava210__at_orgmortbaycomponentAbstra
The only workaround I've been able to find is to simply reboot my computer. Which I find is a trifle bit annoying.
Any ideas?
Just what the error says, you're encountering I/O problems. Per this old posting on the solr-dev mailing list, it sounds like your index directory exists but the index files themselves do not.
If Solr finds the index directory, it assumes the index exists and starts trying to load index files. Hence, the error.
Depending on the actual scenario with your start/stop routines, I would look at what happens with index files on start.

Permission denied for folder creation using background_fu

I am calling a controller method to convert a video file. This process
is called using background_fu job. When the function tries to create a
new folder in rails root it gives error i.e. Permission denied. The
function performs well if not called in background job process.
Can any one point out what can be the trouble.
Thanks in advance,
Anubhaw
Check to see if the background process is running under a different user account to the one being used by your Rails application. On Linux/UNIX you can generally get this information by running the top or ps command.

Resources