Class: Aspire::Caching::Cache

Inherits:
Object
  • Object
show all
Includes:
Util, Exceptions
Defined in:
lib/aspire/caching/cache.rb

Overview

Reads and writes Aspire API data to and from a file-based cache

Constant Summary collapse

MODE =

The default cache directory permissions

0o0750
PATH =

The default cache root directory

'/tmp/aspire/cache'.freeze

Constants included from Util

Util::CACHEABLE

Constants included from Util

Util::LD_API_URI

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#add_filename_prefix, #add_filename_suffix, #cacheable_url, #end_of_path?, #mkdir, #references, #rm, #rmdir_empty, #strip_ext, #strip_filename_prefix, #strip_filename_suffix, #strip_prefix, #strip_suffix

Methods included from Util

#child_url?, #duration, #id_from_uri, #item?, #linked_data, #linked_data_path, #list?, #list_url?, #module?, #parent_url?, #parse_url, #resource?, #section?, #url_for_comparison, #url_path, #user?

Constructor Details

#initialize(ld_api = nil, json_api = nil, path = nil, **options) ⇒ void

Initialises a new Cache instance

Parameters:

  • json_api (Aspire::API::JSON) (defaults to: nil)

    the JSON API instance

  • ld_api (Aspire::API::LinkedData) (defaults to: nil)

    the linked data API instance

  • path (String) (defaults to: nil)

    the cache root directory

  • options (Hash)

    the cache options

Options Hash (**options):

  • :api_retries (Integer)

    the maximum number of retries after an API call timeout

  • :clear (Boolean)

    if true, clear the cache, otherwise leave any existing cache content intact

  • :logger (Logger)

    the cache activity logger

  • :mode (String, Integer)

    the cache directory permissions



50
51
52
53
54
55
56
57
58
59
# File 'lib/aspire/caching/cache.rb', line 50

def initialize(ld_api = nil, json_api = nil, path = nil, **options)
  options ||= {}
  self.json_api = json_api
  self.ld_api = ld_api
  self.logger = Aspire::Caching::CacheLogger.new(options[:logger])
  self.mode = options[:mode] || MODE
  self.path = path || PATH
  # Clear the cache contents if required
  clear if options[:clear]
end

Instance Attribute Details

#json_apiAspire::API::JSON

Returns the JSON API instance.

Returns:



20
21
22
# File 'lib/aspire/caching/cache.rb', line 20

def json_api
  @json_api
end

#ld_apiAspire::API::LinkedData

Returns the linked data API instance.

Returns:



24
25
26
# File 'lib/aspire/caching/cache.rb', line 24

def ld_api
  @ld_api
end

#loggerAspire::Caching::CacheLogger

Returns the cache activity logger.

Returns:



28
29
30
# File 'lib/aspire/caching/cache.rb', line 28

def logger
  @logger
end

#modeString, Integer

Returns the cache directory permissions.

Returns:

  • (String, Integer)

    the cache directory permissions



32
33
34
# File 'lib/aspire/caching/cache.rb', line 32

def mode
  @mode
end

#pathString

Returns the cache root directory.

Returns:

  • (String)

    the cache root directory



36
37
38
# File 'lib/aspire/caching/cache.rb', line 36

def path
  @path
end

Instance Method Details

#cache_entry(url) ⇒ Aspire::Caching::CacheEntry

Returns a CacheEntry instance for the URL

Parameters:

  • url (String)

    the URL of the API object

Returns:



64
65
66
# File 'lib/aspire/caching/cache.rb', line 64

def cache_entry(url)
  CacheEntry.new(ld_api.canonical_url(url), self)
end

#canonical_url(url) ⇒ String

Returns the canonical form of the URL

Parameters:

  • url (String)

    the URL of the API object

Returns:

  • (String)

    the canonical URL of the object



71
72
73
# File 'lib/aspire/caching/cache.rb', line 71

def canonical_url(url)
  ld_api.canonical_url(url)
end

#clearvoid

This method returns an undefined value.

Clears the cache contents

Raises:



78
79
80
81
# File 'lib/aspire/caching/cache.rb', line 78

def clear
  return unless path?
  rm(File.join(path, '*'), logger, 'Cache cleared', 'Cache clear failed')
end

#deletevoid

This method returns an undefined value.

Deletes the cache

Raises:



86
87
88
89
# File 'lib/aspire/caching/cache.rb', line 86

def delete
  return unless path?
  rm(path, logger, 'Cache deleted', 'Cache delete failed')
end

#empty?Boolean

Returns true if the cache is empty, false if not

Returns:

  • (Boolean)

    true if the cache is empty, false if not



93
94
95
# File 'lib/aspire/caching/cache.rb', line 93

def empty?
  Dir.empty?(path)
end

#include?(url = nil, entry: nil) ⇒ Boolean

Returns true if the specified URL is in the cache, false if not

Parameters:

Returns:

  • (Boolean)

    true if the URL is in the cache, false if not



101
102
103
104
# File 'lib/aspire/caching/cache.rb', line 101

def include?(url = nil, entry: nil)
  entry ||= cache_entry(url)
  entry.cached?
end

#linked_data_url(url) ⇒ String

Returns the linked data form of the URL

Parameters:

  • url (String)

    the URL of the API object

Returns:

  • (String)

    the linked data URL of the object



109
110
111
# File 'lib/aspire/caching/cache.rb', line 109

def linked_data_url(url)
  ld_api.linked_data_url(url)
end

#marked_entries(*types) {|url| ... } ⇒ void

This method returns an undefined value.

Iterates over marked (in-progress) cache entries and passes the partial URL path to the block Positional parameters are the object types to include, e.g. ‘lists’, ‘resources’ etc. - default: all object types

Yields:

  • (url)

    passes the list URL to the block

Yield Parameters:

  • url (String)

    the partial linked data URL of the list



139
140
141
142
143
144
145
# File 'lib/aspire/caching/cache.rb', line 139

def marked_entries(*types, &block)
  if types.nil? || types.empty?
    marked_entry('**', &block)
  else
    types.each { |type| marked_entry(type, &block) }
  end
end

#marked_entry(type) {|url| ... } ⇒ void

This method returns an undefined value.

Iterates over a single cache object type and passes the partial object URLs to the block

Parameters:

  • type (String)

    the cache object type (‘lists’, ‘resources’ etc.) or ‘**’ for all object types

Yields:

  • (url)

    passes the partial object URL to the block

Yield Parameters:

  • url (String)

    the partial object URL of the list



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/aspire/caching/cache.rb', line 120

def marked_entry(type)
  Dir.glob(File.join(path, type, '.[^.]*')) do |filename|
    # Convert the filename to a URL and pass to the block
    begin
      entry = CacheEntry.new(filename_to_url(filename), self)
      yield(entry) if block_given?
    rescue NotCacheable
      nil
    end
  end
end

#path?Boolean

Returns true if the cache path is a valid directory

Returns:

  • (Boolean)

    true if the cache path is a valid directory



160
161
162
# File 'lib/aspire/caching/cache.rb', line 160

def path?
  !path.nil? && File.directory?(path)
end

#read(url = nil, entry: nil, json: false, use_api: true, use_cache: true) {|data, flags| ... } ⇒ Hash

Reads an API data object from the cache or API

Parameters:

  • url (String) (defaults to: nil)

    the URL of the API object

  • entry (Aspire::Caching::CacheEntry) (defaults to: nil)

    the cache entry

  • json (Boolean) (defaults to: false)

    if true, read the JSON API, otherwise read the linked data API

  • use_cache (Boolean) (defaults to: true)

    if true, try the cache before the Aspire API

Yields:

  • (data, flags)

    passes the data and flags to the block

Yield Parameters:

  • data (Hash)

    the parsed data from the cache or API call

  • flags (Hash)

    the cache processing flags

  • from_cache (Boolean)

    true if the data was read from the cache, false if it was read from the API

  • json (Boolean)

    true if the data is from the JSON API, false if it is from the linked data API

Returns:

  • (Hash)

    the parsed JSON data from the cache or API

Raises:



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/aspire/caching/cache.rb', line 181

def read(url = nil,
         entry: nil, json: false, use_api: true, use_cache: true)
  entry ||= cache_entry(url)
  # Try the cache, data is nil on a cache miss
  data = use_cache ? read_cache(entry, json: json) : nil
  from_cache = !data.nil?
  # Try the API if nothing was returned from the cache
  data ||= write(entry: entry, json: json) if use_api
  # Call the block if the read was successful
  yield(data, entry, from_cache, json) if block_given? && data
  # Return the data
  data
rescue NotCacheable
  # Uncacheable URLs have no data representation in the Aspire API
  nil
end

#remove(url = nil, entry: nil, force: false, remove_children: false) {|data, entry| ... } ⇒ Hash?

Removes the URL from the cache

Parameters:

  • url (String) (defaults to: nil)

    the URL of the API object

  • entry (Aspire::Caching::CacheEntry) (defaults to: nil)

    the cache entry

  • force (Boolean) (defaults to: false)

    if remove, remove the URL even if it is marked as in-progress; otherwise fails on marked entries

  • remove_children (Boolean) (defaults to: false)

    if true, remove all children of the object as well as the object itself, otherwise remove just the object

Yields:

  • (data, entry)

    passes the data and cache entry to the block

Yield Parameters:

Returns:

  • (Hash, nil)

    the parsed JSON data removed from the cache

Raises:



212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/aspire/caching/cache.rb', line 212

def remove(url = nil, entry: nil, force: false, remove_children: false)
  entry ||= cache_entry(url)
  return nil unless entry.cached?
  # Read the data from the cache for the return value
  data = read_cache(entry)
  # Call the block
  yield(data, entry) if block_given?
  # Remove the cached files
  entry.delete(force: force, remove_children: remove_children)
  # Return the cached data
  data
rescue NotCacheable
  nil
end

#tenancy_hostString

Returns the Aspire tenancy host name

Returns:

  • (String)

    the Aspire tenancy host name



229
230
231
# File 'lib/aspire/caching/cache.rb', line 229

def tenancy_host
  ld_api ? ld_api.tenancy_host : nil
end

#write(url = nil, data: nil, entry: nil, json: false) {|data, entry| ... } ⇒ Hash

Writes an API object to the cache

Parameters:

  • url (String) (defaults to: nil)

    the URL of the API object

  • data (Hash, String, nil) (defaults to: nil)

    parsed or unparsed data to be cached

  • entry (Aspire::Caching::CacheEntry) (defaults to: nil)

    the cache entry

  • json (Boolean) (defaults to: false)

    if true, read the JSON API, otherwise read the linked data API

Yields:

  • (data, entry)

    passes the data and cache entry to the block

Yield Parameters:

Returns:

  • (Hash)

    the parsed JSON data written to the cache

Raises:



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/aspire/caching/cache.rb', line 244

def write(url = nil, data: nil, entry: nil, json: false)
  # Get the cache processing flags
  entry ||= cache_entry(url)
  # Get the data from the API if not supplied
  raw, parsed = write_data(data) || read_api(entry, json: json)
  return nil unless raw && parsed
  # Write the data to the cache
  write_cache(entry, raw, json: json)
  # Call the block
  yield(parsed, entry) if block_given?
  # Return the data written to the cache
  parsed
end