Matthew Williams
2007-Sep-12 12:03 UTC
Need help refactoring a controller, perhaps add threading?
Good morning, I''ve been working on my first Rails app. I''m replacing an old Perl script that scrapes a bunch of data from an Oracle database, generates a bunch of charts then builds a static webpage with the charts. I''ve re-built it in Rails, with about 25% of the code it took to do in Perl and the users can now get dynamic charts instead of day old charts (or whenever the batch runs). I have a view that contains two columns, one for a list of charts and the other with a div container for the charts (called chartDisplay). I have a link for a chart like below: <%= link_to_remote( "Activities by Request", :update => "chartDisplay", :url =>{ :action => :activities_by_request, :name => @project.name }) %> This in turn calls the following in my controller: def activities_by_request @chart_data = ActiveRecord::Base.connection().execute("very long complicated SQL query that I haven''t figured out how to refactor with ActiveRecord yet...") outfile File.open(''public/data/activities_by_request_''+params[:name]+''.csv'', ''wb'') CSV::Writer.generate(outfile) do |csv| @chart_data.each do |cd| csv << [cd["count"],cd["request_title"],cd["state"]] end end outfile.close exec("charting/RequestByProject.jar",params[:name]) render_text ''<br><img src="../../images/charts/requestByProjectBurnSmall_''+params[:name]+''.png'' end (Pastebin URL: http://pastebin.com/m8445781) My problem is occurring at the exec() statement, it completely takes over and freezes everything until it''s finished at which time the render_text inserts the generated chart into my div. This process only takes 4 or so seconds but in that 4 or so seconds I would like to put a message inside the div saying "Your chart is being built" with my spinner animation under it so the user knows that something is going on. I put the exec in a Thread.new{} but I''m not too familiar with how threads function so my render_text line to put up the image was firing before the chart was built. How would I correctly make a look to check thread.alive? to see if it''s finished or not? Ultimately I would like for the user to click the link, populate the div with the text and spinner, generate the chart and place it in the div when finished. I also wasn''t sure if this was a job for an RJS template but the few screencasts I watched didn''t give me the impression I could do what I needed with an RJS template (which I could be very well wrong). However, as my first Rails app, what I''ve accomplished so far just by tutorials and the Agile Rails book is far greater than what I could do in the Perl tool (not to mention adding further capabilities and making it easier to maintain). Thanks in advance for any responses! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Owen van Dommelen
2007-Sep-12 12:45 UTC
Re: Need help refactoring a controller, perhaps add threadin
Definately a job for rjs. You could do something like this in your controller method (which you call with link_to_remote) render :update do |page| page.replace_html "div_id", :partial => "results" end let me know if you need more help. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Matthew Williams
2007-Sep-12 12:49 UTC
Re: Need help refactoring a controller, perhaps add threadin
Daniel Owen van Dommelen wrote:> Definately a job for rjs. You could do something like this in your > controller method (which you call with link_to_remote) > > render :update do |page| > page.replace_html "div_id", :partial => "results" > end > > let me know if you need more help.Could you elaborate on how I can work that logic into an RJS template? Where were :partial come into play? I appreciate it, thanks! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Owen van Dommelen
2007-Sep-12 12:55 UTC
Re: Need help refactoring a controller, perhaps add threadin
Matthew Williams wrote:> Daniel Owen van Dommelen wrote: >> Definately a job for rjs. You could do something like this in your >> controller method (which you call with link_to_remote) >> >> render :update do |page| >> page.replace_html "div_id", :partial => "results" >> end >> >> let me know if you need more help. > > Could you elaborate on how I can work that logic into an RJS template? > > Where were :partial come into play? > > I appreciate it, thanks!The partial is simply some view code you want rendered inside the target div. So basically you create a partial where your chart is rendered. You generate your chart data inside the controller and then you do the render :update do |page| stuff to insert the chart partial inside the div. In your case may even be better to do just this: render :update do |page| page.reaplce_html "target_div", ''<br><img src="../../images/charts/requestByProjectBurnSmall_''+params[:name]+''.png'' end -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Matthew Williams
2007-Sep-12 13:06 UTC
Re: Need help refactoring a controller, perhaps add threadin
Daniel Owen van Dommelen wrote:> Matthew Williams wrote: >> Daniel Owen van Dommelen wrote: >>> Definately a job for rjs. You could do something like this in your >>> controller method (which you call with link_to_remote) >>> >>> render :update do |page| >>> page.replace_html "div_id", :partial => "results" >>> end >>> >>> let me know if you need more help. >> >> Could you elaborate on how I can work that logic into an RJS template? >> >> Where were :partial come into play? >> >> I appreciate it, thanks! > > The partial is simply some view code you want rendered inside the target > div. So basically you create a partial where your chart is rendered. You > generate your chart data inside the controller and then you do the > render :update do |page| stuff to insert the chart partial inside the > div. In your case may even be better to do just this: > > render :update do |page| > page.reaplce_html "target_div", ''<br><img > src="../../images/charts/requestByProjectBurnSmall_''+params[:name]+''.png'' > endNow how do I tie in a spinner and then fire off the exec statement without freezing my app for 5 seconds? That''s the key issue I''m trying to tackle. Thanks for the responses! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Owen van Dommelen
2007-Sep-12 13:10 UTC
Re: Need help refactoring a controller, perhaps add threadin
don''t remember the exact syntax, but check api.rubyonrails.org for that. just check the link_to_remote section, it explains the spinner stuff -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Owen van Dommelen
2007-Sep-12 13:12 UTC
Re: Need help refactoring a controller, perhaps add threadin
Daniel Owen van Dommelen wrote:> don''t remember the exact syntax, but check api.rubyonrails.org for that. > just check the link_to_remote section, it explains the spinner stuffthink it was something like :loading => "yourgifhere.gif" -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Isak Hansen
2007-Sep-12 14:03 UTC
Re: Need help refactoring a controller, perhaps add threading?
On 9/12/07, Matthew Williams <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > My problem is occurring at the exec() statement, it completely takes > over and freezes everything until it''s finished at which time the > render_text inserts the generated chart into my div. This process only > takes 4 or so seconds but in that 4 or so seconds I would like to put a > message inside the div saying "Your chart is being built" with my > spinner animation under it so the user knows that something is going on. > > I put the exec in a Thread.new{} but I''m not too familiar with how > threads function so my render_text line to put up the image was firing > before the chart was built. How would I correctly make a look to check > thread.alive? to see if it''s finished or not? >Most web frameworks frown upon user created/managed threads. This would be fairly esoteric imo, but if you really realy insist, look into BackgrounDRb for running the job asynchronously. Would need some kind of AJAX push library to feed the results to clients when done.> Ultimately I would like for the user to click the link, populate the div > with the text and spinner, generate the chart and place it in the div > when finished. I also wasn''t sure if this was a job for an RJS template > but the few screencasts I watched didn''t give me the impression I could > do what I needed with an RJS template (which I could be very well > wrong).Hmm.. I''d go with two partials. When clicking, load the ''work in progress'' div. Once that completes, start a second remote function to fetch the real contents, e.g. through remote_function''s :completed callback. -Isak --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Matthew Williams
2007-Sep-12 15:01 UTC
Re: Need help refactoring a controller, perhaps add threadin
Isak Hansen wrote:> On 9/12/07, Matthew Williams <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: >> before the chart was built. How would I correctly make a look to check >> thread.alive? to see if it''s finished or not? >> > > Most web frameworks frown upon user created/managed threads. > > This would be fairly esoteric imo, but if you really realy insist, > look into BackgrounDRb for running the job asynchronously. Would need > some kind of AJAX push library to feed the results to clients when > done. > > >> Ultimately I would like for the user to click the link, populate the div >> with the text and spinner, generate the chart and place it in the div >> when finished. I also wasn''t sure if this was a job for an RJS template >> but the few screencasts I watched didn''t give me the impression I could >> do what I needed with an RJS template (which I could be very well >> wrong). > > Hmm.. I''d go with two partials. > > When clicking, load the ''work in progress'' div. Once that completes, > start a second remote function to fetch the real contents, e.g. > through remote_function''s :completed callback. > > > -IsakThat sounds like the best option to me (logically anyway). Could you provide a reference or the basic calls I would use to accomplish calling the functions and working with the :completed callback? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Isak Hansen
2007-Sep-13 08:22 UTC
Re: Need help refactoring a controller, perhaps add threadin
On 9/12/07, Matthew Williams <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Isak Hansen wrote: > > On 9/12/07, Matthew Williams <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > >> before the chart was built. How would I correctly make a look to check > >> thread.alive? to see if it''s finished or not? > >> > > > > Most web frameworks frown upon user created/managed threads. > > > > This would be fairly esoteric imo, but if you really realy insist, > > look into BackgrounDRb for running the job asynchronously. Would need > > some kind of AJAX push library to feed the results to clients when > > done. > > > > > >> Ultimately I would like for the user to click the link, populate the div > >> with the text and spinner, generate the chart and place it in the div > >> when finished. I also wasn''t sure if this was a job for an RJS template > >> but the few screencasts I watched didn''t give me the impression I could > >> do what I needed with an RJS template (which I could be very well > >> wrong). > > > > Hmm.. I''d go with two partials. > > > > When clicking, load the ''work in progress'' div. Once that completes, > > start a second remote function to fetch the real contents, e.g. > > through remote_function''s :completed callback. > > > > > > -Isak > > That sounds like the best option to me (logically anyway). > > Could you provide a reference or the basic calls I would use to > accomplish calling the functions and working with the :completed > callback?See ActionView::Helpers::Prototype*/JavaScript*/Scriptaculous in the API docs. Daniel already explained how you''d write actions that update certain parts of the page, see ActionController::Base#render and ActionView::Base for more info. I think something like this should work: <%= link_to_remote("Load data", :url => {:action => "replace_div_with_spinner"}, :complete => remote_function(:url => {:action => "replace_div_with_real_contents"}) ) %> HTH, Isak> -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Owen van Dommelen
2007-Sep-13 08:29 UTC
Re: Need help refactoring a controller, perhaps add threadin
> I think something like this should work: > > <%= link_to_remote("Load data", :url => {:action => > "replace_div_with_spinner"}, :complete => remote_function(:url => > {:action => "replace_div_with_real_contents"}) ) %> > > > HTH, > IsakI like this one :) Never though about calling a remote function inside the :complete clause. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---