# Expire cache from BackgroundRB async process?

**URL:** <https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634>\
**Category:** Rails\
**Created:** [September 15, 2008, 7:37pm UTC](https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634 "2008-09-15T19:37:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [September 15, 2008, 7:37pm UTC](https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634/1 "2008-09-15T19:37:19Z")

</div>

I’m having some difficulty finding a way to expire the cache after  
executing an asynchronous BackgroundRB task. From a Rails controller I  
fire off an async worker which will handle importing of data from a file  
and, when completed, the fragment cache of a page needs to be expired.  
I’ve tried …

1. Simply calling expire\_action from within the BackgroundRB worker.  
However, it appears that BackgroundRB doesn’t have access to  
ActionController.

2. Using sweepers/observers on the model object being changed by the  
BackgroundRB worker. The BackgroundRB worker will do some stuff with  
the model object, the observer will catch this, and the sweeper will  
handle expiring the cache. However, the sweeper complains that the  
record passed to the after\_whatever callback methods is nil. Without  
this model object I can’t expire the correct cache.

Using Rails 2.1 and the absolute latest BackgroundRB from github.

Any suggestions?

Cheers,  
Justin

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [September 16, 2008, 2:16pm UTC](https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634/2 "2008-09-16T14:16:53Z")

</div>

Hi Justin.

I’ve had the same problem in my application. I need to expire cache  
fragments after completing a rake task.

It seems to be no way to call sweepers/observers from outside the  
controller, so I did this little trick:

In one of my controllers I created a public method:

def expire\_my\_fragments  
expire\_fragment(‘’)  
end

then in the rake task I’ve added in the bottom of the method:

task :start\_my\_custom\_task =\> :environment do  
do\_something()  
require ‘action\_controller/integration’  
app = ActionController::Integration::Session.new  
app.get(‘/my\_controller/expire\_my\_fragments’)  
end

As you can see, I call an integration test after the end of my task.  
Finally, if you want that the integration test expires your fragments,  
you need to invoke your task with production environment parameters:

rake environment RAILS\_ENV=production start\_my\_custom\_task

I hope you find this useful.

Cheers, Stefano

On Sep 15, 7:37 pm, Justin B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [September 16, 2008, 11:19pm UTC](https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634/3 "2008-09-16T23:19:49Z")

</div>

Justin B. wrote:

> I’m having some difficulty finding a way to expire the cache after  
> executing an asynchronous BackgroundRB task. From a Rails controller I  
> fire off an async worker which will handle importing of data from a file  
> and, when completed, the fragment cache of a page needs to be expired.  
> I’ve tried …
> 
> 1. Simply calling expire\_action from within the BackgroundRB worker.  
> However, it appears that BackgroundRB doesn’t have access to  
> ActionController.
> 
> 2. Using sweepers/observers on the model object being changed by the  
> BackgroundRB worker. The BackgroundRB worker will do some stuff with  
> the model object, the observer will catch this, and the sweeper will  
> handle expiring the cache. However, the sweeper complains that the  
> record passed to the after\_whatever callback methods is nil. Without  
> this model object I can’t expire the correct cache.
> 
> Using Rails 2.1 and the absolute latest BackgroundRB from github.
> 
> Any suggestions?
> 
> Cheers,  
> Justin

Have you tried using Rails.cache.delete(cache\_path) from the model?

The sweepers weren’t fine-grained enough for my fragment caching, and I  
ended up just taking control of the cache expiration (for my app, a  
single model may have, oh, 8 different fragments cached, and it may  
appear in cache fragments of any number of other models – polymorphic  
relationships are cool, but have their downside – so depending on what  
changed, a model knows what caches it should expire of its own, and if  
fragments of models it has a relationship with should expire also -  
i.e., my name field changed and that other model’s cache shows my name).

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [September 17, 2008, 12:00am UTC](https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634/4 "2008-09-17T00:00:15Z")

</div>

The problem is that the model object doesn’t seem to be available to the  
callback function.

For example, in the sweeper:  
observe MyModel

def after\_create(record)  
expire the cache  
end

And, in the BackgroundRB worker:  
MyModel.create()

And when the BackgroundRB async task is started, the MyModel  
after\_create() method is invoked as expected; however, record is nil (as  
is self).

The record has some info in it that I use to calculate the path to  
expire. So, I can’t call Rails.cache.delete(cache\_path) when I can’t  
determine the value of cache\_path.

Thanks for taking the time to help,  
Justin

Ar Chron wrote:

> Justin B. wrote:
> 
> > I’m having some difficulty finding a way to expire the cache after  
> > executing an asynchronous BackgroundRB task. From a Rails controller I  
> > fire off an async worker which will handle importing of data from a file  
> > and, when completed, the fragment cache of a page needs to be expired.  
> > I’ve tried …
> > 
> > 1. Simply calling expire\_action from within the BackgroundRB worker.  
> > However, it appears that BackgroundRB doesn’t have access to  
> > ActionController.
> > 
> > 2. Using sweepers/observers on the model object being changed by the  
> > BackgroundRB worker. The BackgroundRB worker will do some stuff with  
> > the model object, the observer will catch this, and the sweeper will  
> > handle expiring the cache. However, the sweeper complains that the  
> > record passed to the after\_whatever callback methods is nil. Without  
> > this model object I can’t expire the correct cache.
> > 
> > Using Rails 2.1 and the absolute latest BackgroundRB from github.
> > 
> > Any suggestions?
> > 
> > Cheers,  
> > Justin
> 
> Have you tried using Rails.cache.delete(cache\_path) from the model?
> 
> The sweepers weren’t fine-grained enough for my fragment caching, and I  
> ended up just taking control of the cache expiration (for my app, a  
> single model may have, oh, 8 different fragments cached, and it may  
> appear in cache fragments of any number of other models – polymorphic  
> relationships are cool, but have their downside – so depending on what  
> changed, a model knows what caches it should expire of its own, and if  
> fragments of models it has a relationship with should expire also -  
> i.e., my name field changed and that other model’s cache shows my name).

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [September 17, 2008, 4:42pm UTC](https://www.ruby-forum.com/t/expire-cache-from-backgroundrb-async-process/148634/5 "2008-09-17T16:42:55Z")

</div>

Justin B. wrote:

> The problem is that the model object doesn’t seem to be available to the  
> callback function.
> 
> For example, in the sweeper:  
> observe MyModel
> 
> def after\_create(record)  
> expire the cache  
> end
> 
> And, in the BackgroundRB worker:  
> MyModel.create()
> 
> And when the BackgroundRB async task is started, the MyModel  
> after\_create() method is invoked as expected; however, record is nil (as  
> is self).
> 
> The record has some info in it that I use to calculate the path to  
> expire. So, I can’t call Rails.cache.delete(cache\_path) when I can’t  
> determine the value of cache\_path.
> 
> Thanks for taking the time to help,  
> Justin

If there’s something wrong with BackgroundRB and sweepers, have you  
tried:

In the BackgroundRB worker:

my\_model = MyModel.create(blah blah blah)  
my\_model.clear\_the\_cache

and inside MyModel

def clear\_the\_cache  
Rails.cache.clear(cache\_path from data)  
end

AR.create _should_ be handing back a model, which could self-inspect to  
derive the cache path to expire…
