[ANN] Boogaloo Simple Cache Server 0.1

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/
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.

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

···

On 10/14/06, Ian Leitch <port001@gmail.com> wrote:

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/
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.

--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.

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

···

On 15/10/06, hemant <gethemant@gmail.com> wrote:

On 10/14/06, Ian Leitch <port001@gmail.com> wrote:
> 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/
> 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.
>

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

--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.

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

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

···

On 10/15/06, Nicholas Frechette <nicholas.gravel-frechette@usherbrooke.ca> wrote:

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

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.

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

···

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:

--
my religion is very simple. my religion is kindness. -- the dalai lama

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

David Vallner