Forum: Ruby on Rails cancel periodically_call_remote?

0f50b9a2ad85666d537d39bda49327ee?d=identicon&s=25 Jonathan Rochkind (jrochkind)
on 2007-07-25 22:25
So I have a periodically_call_remote call happenign every 5 seconds.
After about 10-20 seconds at most, everything that it needs to do is
done, and it doesn't need to fire anymore.

Now, I can take advantage of the :condition argument to put in some
javascript variable such that it won't actually make the call to the
server anymore. But the javascript timer is still firing--every five
seconds it's deciding not to make the call to the server anymore.

If I leave the window open long enough, or have enough such windows
open, this starts causing noticeable slowdown in my browser. (Perhaps
some kidn of Firefox memory leak, perhaps not, who knows). I really want
the thing to just stop firing--not to fire every five seconds and check
to see if it should make the XML call to server, but just not fire at
all anymore, it's done.

Is there any good way to do this?

Thanks for any advice.

Jonathan
1b975fda3889504d53a9726914d64fd2?d=identicon&s=25 Rusty Burchfield (Guest)
on 2007-07-26 00:46
(Received via mailing list)
On Jul 25, 4:25 pm, Jonathan Rochkind <rails-mailing-l...@andreas-
s.net> wrote:
> I really want
> the thing to just stop firing--not to fire every five seconds and check
> to see if it should make the XML call to server, but just not fire at
> all anymore, it's done.
>
> Is there any good way to do this?

You could try putting the periodically call remote inside a div, and
have the last periodic call clear the div.

~Rusty
832ed6ace46d61032151f4e1864c057f?d=identicon&s=25 Solid (Guest)
on 2007-07-26 00:46
(Received via mailing list)
Hello,

Have you tried this:
http://tr.openmonkey.com/articles/2006/01/23/condi...

Dmitry

On Jul 25, 11:25 pm, Jonathan Rochkind <rails-mailing-l...@andreas-
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2007-07-26 00:46
(Received via mailing list)
Rusty Burchfield wrote:

> You could try putting the periodically call remote inside a div, and
> have the last periodic call clear the div.

This is a FAQ, and that's wrong because the setTimeout still exists,
and it will still reactivate that object in memory. The DIV only
creates it and pushes it into memory.

I say leave the dumb thing spinning on the user's browser. They have
CPU cycles - you don't!

--
 Phlip
 http://www.oreilly.com/catalog/9780596510657/
 ^ assert_xpath
 http://tinyurl.com/23tlu5  <-- assert_raise_message
1b975fda3889504d53a9726914d64fd2?d=identicon&s=25 Rusty Burchfield (Guest)
on 2007-07-26 07:27
(Received via mailing list)
On Jul 25, 5:58 pm, Phlip <phlip2...@gmail.com> wrote:
> Rusty Burchfield wrote:
> > You could try putting the periodically call remote inside a div, and
> > have the last periodic call clear the div.
>
> This is a FAQ, and that's wrong because the setTimeout still exists,
> and it will still reactivate that object in memory. The DIV only
> creates it and pushes it into memory.

Emphasis on try.

This might work for you.  Create a variable and function, for example:
IWantToContinue = true;
function continueOrNot() {
if (IWantToContinue) return true;
this.stop();
return false;
}

Then set :condition=>"continueOrNot()", and set IWantToContinue to
false with rjs when you are done.

To test it you can set :condition=>"continueOrNot() || alert('still
executing...')"

~Rusty
0f50b9a2ad85666d537d39bda49327ee?d=identicon&s=25 Jonathan Rochkind (jrochkind)
on 2007-07-26 15:40
Rusty Burchfield wrote:
> This might work for you.  Create a variable and function, for example:
> IWantToContinue = true;
> function continueOrNot() {
> if (IWantToContinue) return true;
> this.stop();
> return false;
> }

That's an interesting idea. Haven't tried it yet, but it led me to
another idea, after looking at the source code generated by
periodically_call_remote, and tryign to understand what your this.stop()
did.

My new idea: stop using periodically_call_remote at all. Instead,
generate the Prototype javascript myself manually (based on the source
code I see periodically_call_remote generating), to do exactly the same
thing, but save the  Prototype PeriodicalExecuter js object in a js
variable:

some_js_var = new PeriodicialExecuter(...

Now I can just call some_js_var.stop() at a future point. I think this
should work.

If the periodically_call_remote function were enhanced to take an
argument for a name of a js variable to use in this assignment (not sure
what you'd name this argument!), that would allow the
periodically_call_remote to be used itself, and take care of this FAQ!

Jonathan


>
> Then set :condition=>"continueOrNot()", and set IWantToContinue to
> false with rjs when you are done.
>
> To test it you can set :condition=>"continueOrNot() || alert('still
> executing...')"
>
> ~Rusty
84dc80a5c0ac9fe04f1463d6c6cdb10f?d=identicon&s=25 Micah Winkelspecht (wink)
on 2008-08-27 10:43
I took this idea and implemented it in my app.

In ApplicationHelper, I overrode the periodically_call_remote function
with:

  def periodically_call_remote(options = {})
    variable = options[:variable] ||= 'poller'
    frequency = options[:frequency] ||= 10
    code = "#{variable} = new PeriodicalExecuter(function()
{#{remote_function(options)}}, #{frequency})"
    javascript_tag(code)
  end

This will store the PeriodicalExecuter in a variable. In order to set
the name of the variable, you can pass in a :variable option. By
default, it will use 'poller'.

So you can do:

periodically_call_remote(:url => some_url, :update => 'some_div',
:variable => 'my_var')

And when you want to stop the polling, you can inject the following line
of javascript into your page:

<script>
  my_var.stop();
</script>

Hope this helps anyone else who's run into this.

Micah Winkelspecht


> My new idea: stop using periodically_call_remote at all. Instead,
> generate the Prototype javascript myself manually (based on the source
> code I see periodically_call_remote generating), to do exactly the same
> thing, but save the  Prototype PeriodicalExecuter js object in a js
> variable:
>
> some_js_var = new PeriodicialExecuter(...
>
> Now I can just call some_js_var.stop() at a future point. I think this
> should work.
>
> If the periodically_call_remote function were enhanced to take an
> argument for a name of a js variable to use in this assignment (not sure
> what you'd name this argument!), that would allow the
> periodically_call_remote to be used itself, and take care of this FAQ!
>
> Jonathan
Dc8dd0e6eb76f9e89d55617cdc9ed8e7?d=identicon&s=25 nfstern (Guest)
on 2009-01-16 22:34
(Received via mailing list)
Another thing you can do is to change the frequency to a very high
number after your desired condition is met.  Technically, this doesn't
cancel it, but it works.

On Aug 27 2008, 2:43 am, Micah Winkelspecht <rails-mailing-
Db6295acf763d2596d562e30079d859b?d=identicon&s=25 Jason Dely (dalekleader)
on 2010-03-01 21:01
This seems to be what I was loooking for.
Now what I would like to know is how can I restart the call?
Can I push it from the server based on new data now available?

What I am trying to accomplish is to only update a dom when data in the
database has changed.

Thanks

Micah Winkelspecht wrote:
> I took this idea and implemented it in my app.
>
> In ApplicationHelper, I overrode the periodically_call_remote function
> with:
>
>   def periodically_call_remote(options = {})
>     variable = options[:variable] ||= 'poller'
>     frequency = options[:frequency] ||= 10
>     code = "#{variable} = new PeriodicalExecuter(function()
> {#{remote_function(options)}}, #{frequency})"
>     javascript_tag(code)
>   end
>
> This will store the PeriodicalExecuter in a variable. In order to set
> the name of the variable, you can pass in a :variable option. By
> default, it will use 'poller'.
>
> So you can do:
>
> periodically_call_remote(:url => some_url, :update => 'some_div',
> :variable => 'my_var')
>
> And when you want to stop the polling, you can inject the following line
> of javascript into your page:
>
> <script>
>   my_var.stop();
> </script>
280b78a61a968391b7e07e912be102a8?d=identicon&s=25 Robert Walker (robert4723)
on 2010-03-02 17:03
Jason Dely wrote:
> This seems to be what I was loooking for.
> Now what I would like to know is how can I restart the call?
> Can I push it from the server based on new data now available?

I ran into these issue myself. After much struggle and frustration, it
dawned on me that doing periodic updates with straight up JavaScript is
really pretty easy. And, I found it to be more flexible anyway.

Here is an example of my solution. This happens to be jQuery, but the
same applies to Prototype:
------------------------
var myInterval;

// Wait for DOM to load
$(document).ready(function() {
  startUpdater();

  // Setup start/stop buttons
  $("#stop_refresh").click(stopUpdater);
  $("#start_refresh").click(startUpdater);
});

function startUpdater() {
  myInterval = window.setInterval(doUpdate, 2000);
}

function stopUpdater() {
  window.clearInterval(myInterval);
  return false;
}

function doUpdate() {
  var url = "url/to/new/content";
  $("#content_div").load(url);
}
------------------------
Note: this is also an Unobtrusive JavaScript solution, which is another
bonus.
7ea637318b43f3a89c39cd0614af0a57?d=identicon&s=25 Vicer Ontero (vicer)
on 2010-06-11 06:03
Micah Winkelspecht wrote:
>   def periodically_call_remote(options = {})
>     variable = options[:variable] ||= 'poller'
>     frequency = options[:frequency] ||= 10
>     code = "#{variable} = new PeriodicalExecuter(function()
> {#{remote_function(options)}}, #{frequency})"
>     javascript_tag(code)
>   end

Thanks alot! Helped me fix the problem as well.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.