Send_file, RRDtool, require or session problem


#1

Hi all,

I am new to RoR and ruby, but am a very experience PHP developer. Let
me give an overview of the problem.

I have a model Latency, which contains username, graph_name so the
logged in user can see his/her latency graphs.

In my ViewController I have a fuction view_latency which pulls the
correct latency object and runs latency.overview. latency.overview
creates a .png file in /tmp, and view_latency then sends this using
send_file to an image tag on the man page.

latency.overview uses RRDtool(from rrdtool.rubyforge.org) to create the
.png file from a .rrd. I have put require ‘RRDtool’ in
config/environment.rb. I have also tried putting it in my latency.rb
model, but it doesn’t change the problem I’m having which is:

When a user has only one graph, this works perfectly. As soon as there
is more than one graph on the main page, no image is returned and the
“no image” icon is displayed in FireFox. If I ‘View Image’ directly,
there is no image and “Application error (Rails)” in an

is shown.
The logs for webrick don’t show anything out of the ordinary, but
tail’ing development.log shows the error stated below.

If I restart webrick, and hit on refresh in FireFox, it works again. I
can jump up and down on refresh all I want, even go to another graph
directly and all is good. Then when I go back to the page with many
graphs, it falls over again.

I have a feeling it is something to do with the session being locked
(shrug) but I have no idea where to go from here. Please could
someone help.

Error from development.log:

Rendering
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/templates/rescues/layout.rhtml
(500 Internal Error)
No such file or directory -
script/…/config/…/tmp/sessions//ruby_sess.9ef57d1cafefb676
/usr/lib/ruby/1.8/pstore.rb:290:in initialize' /usr/lib/ruby/1.8/pstore.rb:290:intransaction’
/usr/lib/ruby/1.8/cgi/session/pstore.rb:90:in update' /usr/lib/ruby/1.8/cgi/session/pstore.rb:97:inclose’
/usr/lib/ruby/1.8/cgi/session.rb:330:in close' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:984:inclose_session’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:1026:in
process_cleanup_without_flash' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/flash.rb:147:inprocess_cleanup_without_filters’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:439:in
process_cleanup_without_session_management_support' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/session_management.rb:126:inprocess_cleanup_without_components’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/components.rb:182:in
process_cleanup' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:385:inprocess_without_filters’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:377:in
process_without_session_management_support' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/session_management.rb:117:inprocess’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/dispatcher.rb:38:in
dispatch' /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:115:inhandle_dispatch’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:81:in
service' /usr/lib/ruby/1.8/webrick/httpserver.rb:104:inservice’
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in run' /usr/lib/ruby/1.8/webrick/server.rb:173:instart_thread’
/usr/lib/ruby/1.8/webrick/server.rb:162:in start_thread' /usr/lib/ruby/1.8/webrick/server.rb:95:instart’
/usr/lib/ruby/1.8/webrick/server.rb:92:in start' /usr/lib/ruby/1.8/webrick/server.rb:23:instart’
/usr/lib/ruby/1.8/webrick/server.rb:82:in start' /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/webrick_server.rb:67:indispatch’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/servers/webrick.rb:59
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in require' /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:inrequire’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/server.rb:30
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in require' /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:inrequire’
script/server:3


#2

On Sun, 2006-05-14 at 14:23 +0200, John O. wrote:

Hi all,

When a user has only one graph, this works perfectly. As soon as there
is more than one graph on the main page, no image is returned and the
“no image” icon is displayed in FireFox. If I ‘View Image’ directly,
there is no image and “Application error (Rails)” in an

is shown.
The logs for webrick don’t show anything out of the ordinary, but
tail’ing development.log shows the error stated below.

I’d do this differently myself:

  1. Create a directory in public/graphs
  2. As each user generates a graph, create a
    public/graphs//.png file. Keep the graphid consistent
    so that you can just rewrite it when the graph changes.
  3. When the user requests a graph, you can do one of the following:
    a) Update any graphs that have changed and then render the page with
    just the img src pointing at the right graph. This has the advantage
    that your web server and not rails is serving the graphs.
    b) That won’t work if the users are authenticated. In this case,
    check out X-Sendfile as a response header and use that in your small
    action that authenticates them prior to sending the graph back. You web
    server will then still authenticate them through rails, but will use
    X-Sendfile and serve the file directly. Probably want to secure the
    public/graphs dir as well.
    c) If X-Sendfile doesn’t graph you then there’s various
    authentication schemes available to apache that you might be able to use
    to serve the files as static files but still authenticate the user.

The gist of the recommendation is don’t write the files to /tmp, cache
them in a consistent place that’s accessible by your web server, and
just have your web server deliver them. If you get the caching right
you can probably avoid a huge amount of processing as well.


Zed A. Shaw


http://mongrel.rubyforge.org/