Class: InstantCache::Counter

Inherits:
Blob
  • Object
show all
Defined in:
lib/instantcache.rb

Overview

Class for integer-only memcache cells, capable of atomic increment/decrement. Basically the same as Blob, except with a default reset value of zero and rawmode forced to true.

However, counters have some additional features:

  • They may only be set to integer values;

  • varname_increment and varname_decrement methods, which provide access to the corresponding underlying memcache atomic integer operations;

  • Decrementing stops at zero, and will not result in negative numbers (a feature of memcache).

Constant Summary collapse

RESET_VALUE =

When a cached ‘counter’ value is reset or cleared, that means ‘zero’.

0

Instance Attribute Summary

Attributes inherited from Blob

#expiry, #identity, #locked_by_us, #rawmode

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Blob

#create_identity, #destroy!, #destroyed?, #lock, memcached_accessor, memcached_reader, #name, #reset, #to_s, #unlock

Constructor Details

#initialize(inival = nil) ⇒ Counter

Description

As with Blob#initialize, this is not intended to be called directly. Rather, instances are declared with the #memcached_counter class method.

:call-seq: memcached_counter(symbol[,…]) memcached_counter(symbol[,…]) { |symbol| … }

Arguments

symbol

As with other Ruby accessor declarations, the argument list consists of one or more variable names represented as symbols (e.g., :variablename).

:call-seq:

block

If a block is supplied, its return value must be a string, which will be used as the name of the memcached cell backing the variable. The argument to the block is the name of the variable as passed to the accessor declaration.

Exceptions

None.



891
892
893
894
# File 'lib/instantcache.rb', line 891

def initialize(inival=nil)
  @rawmode = true
  return super
end

Class Method Details

.memcached_counter(*args, &block) ⇒ Object

Description

Access method declarator for an interlocked shared integer memcache-backed variable.

This declarator sets up several methods relating to the variable. If the name passed is :ivar, these methods are created for it:

ivar

Normal read accessor (e.g., obj.ivar). (See Blob#get)

ivar_reset

Resets the cache variable to the default ‘uninitialised’ value. (See Blob#reset)

ivar_expiry

Returns the current cache lifetime (default 0). (See Blob#expiry)

ivar_expiry=

Sets the cache lifetime. (See Blob#expiry=)

ivar_lock

Tries to get an exclusive lock on the variable. (See Blob#lock)

ivar_unlock

Unlocks the variable if locked. (See Blob#unlock)

ivar_destroyed?

Returns true if variable is disconnected from the cache and unusable. (See Blob#destroyed?)

ivar_destroy!

Disconnects the variable from the cache and makes it unusable. (See Blob#destroy!)

(These are the same methods created for a Blob::memcached_accessor declaration.)

In addition, the following counter-specific methods are created:

ivar_increment

Adds the specified value to the cache variable. (See Counter#increment)

ivar_incr

Alias for ivar_increment.

ivar_decrement

Subtracts from the cache variable. (See Counter#decrement)

ivar_decr

Alias for ivar_decrement.

:call-seq: memcached_counter(symbol[,…]) memcached_counter(symbol[,…]) { |symbol| … }

Arguments

symbol

As with other Ruby accessor declarations, the argument list consists of one or more variable names represented as symbols (e.g., :variablename).

block

If a block is supplied, its return value must be a string, which will be used as the name of the memcached cell backing the variable. The argument to the block is the name of the variable as passed to the accessor declaration.

Exceptions

None.

– This will be overridden later, but we need to declare something for the rdoc generation to work. ++



858
# File 'lib/instantcache.rb', line 858

def memcached_counter(*args, &block) ; end

Instance Method Details

#decrement(amt = 1) ⇒ Object Also known as: decr

Description

Decrement a memcached cell. This only works in raw mode, which is why it’s in this class rather than Blob, but it’s implicitly atomic according to memcache semantics.

:call-seq: decrement[(by_amount)] => Integer

Arguments

by_amount

An integer amount by which to reduce the value of the variable; default is 1.

Exceptions

InstantCache::CounterIntegerOnly

The supplied value was not an integer, and the cache was not changed.

InstantCache::Destroyed

Cache value instance has been destroyed and is no longer usable. The value in the cache is unaffected.

Raises:



994
995
996
997
998
999
1000
1001
1002
1003
# File 'lib/instantcache.rb', line 994

def decrement(amt=1)
  raise Destroyed.new(self.name) if (self.destroyed?)
  unless (amt.kind_of?(Integer))
    raise CounterIntegerOnly.new(self.ivar_name.inspect)
  end
  #
  # TODO: Another instance of poor-man's-cache-location; see #reset
  #
  return InstantCache.cache.decr(self.name, amt)
end

#getObject

Description

Fetch the cached value through the superclass, and convert it to integer. (Raw values get stored as strings, since they’re unmarshalled.)

Arguments

None.

Exceptions

InstantCache::Destroyed

Cache value instance has been destroyed and is no longer usable. The value in the cache is unaffected. (From Blob#get)



911
912
913
# File 'lib/instantcache.rb', line 911

def get
  return super.to_i
end

#increment(amt = 1) ⇒ Object Also known as: incr

Description

Increment a memcached cell. This only works in raw mode, which is why it’s in this class rather than Blob, but it’s implicitly atomic according to memcache semantics.

:call-seq: increment[(by_amount)] => Integer

Arguments

by_amount

An integer amount by which to increase the value of the variable; default is 1.

Exceptions

InstantCache::CounterIntegerOnly

The supplied value was not an integer, and the cache was not changed.

InstantCache::Destroyed

Cache value instance has been destroyed and is no longer usable. The value in the cache is unaffected.

Raises:



960
961
962
963
964
965
966
967
968
969
# File 'lib/instantcache.rb', line 960

def increment(amt=1)
  raise Destroyed.new(self.name) if (self.destroyed?)
  unless (amt.kind_of?(Integer))
    raise CounterIntegerOnly.new(self.ivar_name.inspect)
  end
  #
  # TODO: Another instance of poor-man's-cache-location; see #reset
  #
  return InstantCache.cache.incr(self.name, amt)
end

#set(val) ⇒ Object

Description

Store a value as an integer, and return the value as stored. See Blob#set for the significance of this operation.

Arguments

val

New value to be stored in the cached cell.

Exceptions

InstantCache::CounterIntegerOnly

The supplied value was not an integer, and was not stored.

InstantCache::Destroyed

Cache value instance has been destroyed and is no longer usable. The value in the cache is unaffected.



931
932
933
934
935
936
# File 'lib/instantcache.rb', line 931

def set(val)
  unless (val.kind_of?(Integer))
    raise CounterIntegerOnly.new(self.ivar_name.inspect)
  end
  return super(val.to_i).to_i
end