# Boogaloo Simple Cache Server 0.1

**URL:** <https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076>\
**Category:** Ruby\
**Created:** [October 14, 2006, 1:18am UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076 "2006-10-14T01:18:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 14, 2006, 1:18am UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/1 "2006-10-14T01:18:25Z")

</div>

Hey all,

I’ve just made the first release of a new project: Boogaloo.

Boogaloo is a very simple cache server that provides persistent and  
temporary caches. You can also use it to house your own custom services.  
It’s meant to be very simple to use so that you can concentrate on your  
primary problem.

You’ll find it fully documented and even has a few unit tests:  
[http://boogaloo.rubyforge.org/](http://boogaloo.rubyforge.org/)  
or “sudo gem install boogaloo” if you want to play straight away.

Why?

It started out as a place to cache my rendered Liquid template objects  
and  
somewhere to store a list of selectors from some CSS files. Later on I  
started using it as a temporary cache for objects that were only  
relevant to  
specific user in Rails. So instead of keeping the object in the users  
session and forgetting to clear it out later, I can now just stick it in  
Boogaloo and let it expire after a period given. This is very handy for  
multi-step forms etc.

Anyway, I hope someone finds it useful…

Cheers,  
Ian.

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 15, 2006, 7:43am UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/2 "2006-10-15T07:43:41Z")

</div>

On 10/14/06, Ian L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> [http://boogaloo.rubyforge.org/](http://boogaloo.rubyforge.org/)  
> multi-step forms etc.
> 
> Anyway, I hope someone finds it useful…
> 
> Cheers,  
> Ian.

Interesting, so where do you cache the data that clients send you?

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 15, 2006, 3:00pm UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/3 "2006-10-15T15:00:17Z")

</div>

Currently they’re only cached in memory, I could add pickle the cache to  
disk on server shutdown if there is demand for it.

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 15, 2006, 3:20pm UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/4 "2006-10-15T15:20:21Z")

</div>

Hi, I’m currently working on a side project which has me store binary  
content in memory.  
In order to make it’s use as transparent as possible, i overloaded the  
‘require’ method to search as well in the memory and this works fine at  
the moment. In the same line of thought, I tried changing the way  
File.new works to return a StringIO object pointing to my binary data in  
memory instead of an ordinary IO object… However, i ran into an  
interesting problem. Consider the following code:

class File  
alias\_method :old\_new, :initialize

```
def initialize(*args)
    if args[0] == 'a.txt'
        # Do not return a file object, return say, a Hash
        Hash.new
    else
        old_new(*args)
    end
end

```

end

o = File.new(‘a.txt’)  
puts “Object is of class: #{o.class}”

This outputs:  
Object is of class: File

Obviously. Now, looking further for alternatives, i tried to overload  
Class.new. Consider the following code:  
class Foo  
end

class Bar  
end

class Class  
alias oldNew new  
def new(\*args)  
print "Creating a new ", self.name, “\n”  
if self.name == ‘File’  
require ‘stringio’  
StringIO.new(‘This is a string!’,‘r’)  
elsif self.name == ‘Foo’  
Bar.new  
else  
oldNew(\*args)  
end  
end  
end

d = Foo.new  
puts “Should be type Foo and is: #{d.class}”  
n = File.new(‘lol.rb’,‘r’)  
puts “Should be type StringIO and is: #{n.class}”  
puts “Content is: #{n.read}”

With a file named lol.rb in my path with the single line of content:  
“Hello”, this outputted:  
Creating a new Foo  
Creating a new Bar  
Should be type Foo and is: Bar  
Should be type StringIO and is: File  
Content is: Hello

==========================  
Two things here:  
Class.new is working as expected with Foo, returning a Bar object. But,  
when File.new is called, Class.new is not called as it was for Foo.new!

Any thoughts/help please? I have ran out of ideas… An obvious solution  
is to use a different constructor that is not File.new but that would  
make it not very elegant.

Thanks and regards.  
Nicholas

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 15, 2006, 4:38pm UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/5 "2006-10-15T16:38:30Z")

</div>

On Sun, 15 Oct 2006, Nicholas Frechette wrote:

> Hi, I’m currently working on a side project which has me store binary  
> content in memory. In order to make it’s use as transparent as possible, i  
> overloaded the ‘require’ method to search as well in the memory and this  
> works fine at the moment. In the same line of thought, I tried changing the  
> way File.new works to return a StringIO object pointing to my binary data in  
> memory instead of an ordinary IO object… However, i ran into an  
> interesting problem. Consider the following code:

the way to accomplish this is to use mmap. that’s what the call  
basically  
does: map file to memory and return them as strings. if you create more  
than  
one mapping you will not map the file twice (if you give the right flags  
to  
the ctor). here’s a little example of using mmap to modify the running  
program:

here’s the program

```
 harp:~ > cat a.rb
 require 'mmap'

 mmap = Mmap.new __FILE__ , 'rw', Mmap::MAP_SHARED

 mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
 mmap.msync
 mmap.munmap

 p DATA.readlines

 __END__

```

here’s one run

```
 harp:~ > ruby a.rb
 ["{#<Mmap:0xb75cc79c>=>\"1160922660.6115\"}\n"]

 harp:~ > cat a.rb
 require 'mmap'

 mmap = Mmap.new __FILE__ , 'rw', Mmap::MAP_SHARED

 mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
 mmap.msync
 mmap.munmap

 p DATA.readlines

 __END__
 {#<Mmap:0xb75cc79c>=>"1160922660.6115"}

```

here’s the next

```
 harp:~ > ruby a.rb
 ["{#<Mmap:0xb75cc79c>=>\"1160922660.6115\"}\n", 

```

“{#Mmap:0xb75d079c=\>“1160922666.11629”}\n”]

```
 harp:~ > cat a.rb
 require 'mmap'

 mmap = Mmap.new __FILE__ , 'rw', Mmap::MAP_SHARED

 mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
 mmap.msync
 mmap.munmap

 p DATA.readlines

 __END__
 {#<Mmap:0xb75cc79c>=>"1160922660.6115"}
 {#<Mmap:0xb75d079c>=>"1160922666.11629"}

```

as many times as you might call " Mmap.new **FILE** , ‘rw’,  
Mmap::MAP\_SHARED "  
your process will only have one mapping. in fact, you really cannot map  
it  
more times:

```
 harp:~ > cat a.rb
 require 'mmap'

 mmaps = Array.new(3){ Mmap.new __FILE__ , 'rw', Mmap::MAP_SHARED }

 mmaps.each do |mmap|
   mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
   mmap.msync
   mmap.munmap
 end

 p DATA.readlines

 __END__

 harp:~ > ruby a.rb
 ["{#<Mmap:0xb75d179c>=>\"1160922968.42437\"}\n"]

 harp:~ > cat a.rb
 require 'mmap'

 mmaps = Array.new(3){ Mmap.new __FILE__ , 'rw', Mmap::MAP_SHARED }

 mmaps.each do |mmap|
   mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
   mmap.msync
   mmap.munmap
 end

 p DATA.readlines

 __END__
 {#<Mmap:0xb75d179c>=>"1160922968.42437"}

```

notice how the second and third calls were no-ops. that’s because all  
three  
mappings were actually the same, and unmapping the first unmapped the  
rest -  
leaving the rest of the loops as no-ops.

regards.

-a

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 15, 2006, 3:58pm UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/6 "2006-10-15T15:58:26Z")

</div>

On 10/15/06, Nicholas Frechette  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> old_new(*args)
> 
> ```
> 
> Any thoughts/help please? I have ran out of ideas… An obvious solution  
> is to use a different constructor that is not File.new but that would  
> make it not very elegant.

SomeClass#initialize is not SomeClass::new, only the return value of  
new decides what the returned object is.  
As for overriding Class::new, that’s just not necessary and there  
probably is a File::new or IO::new that prevents Class::new from being  
called.

Try  
class File  
alias …  
def self.new(\*args)  
if …  
return {}  
else  
old\_new(\*args)  
end  
end

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [October 15, 2006, 6:46pm UTC](https://www.ruby-forum.com/t/boogaloo-simple-cache-server-0-1/72076/7 "2006-10-15T18:46:46Z")

</div>

Please don’t hijack threads, it makes a mess of things. Thanks.

David V.
