Class: Aspire::Caching::CacheEntry

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

Overview

Represents an entry in the cache

Constant Summary

Constants included from Util

Util::LD_API_URI

Constants included from Util

Util::CACHEABLE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

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

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

Constructor Details

#initialize(url, cache) ⇒ void

Initialises a new CacheEntry instance

Parameters:

Raises:



40
41
42
43
# File 'lib/aspire/caching/cache_entry.rb', line 40

def initialize(url, cache)
  self.cache = cache
  self.url = url
end

Instance Attribute Details

#cacheAspire::Caching::Cache

Returns the cache.

Returns:



15
16
17
# File 'lib/aspire/caching/cache_entry.rb', line 15

def cache
  @cache
end

#json_api_optHash

Returns #call parameters for the JSON API call.

Returns:

  • (Hash)

    #call parameters for the JSON API call



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

def json_api_opt
  @json_api_opt
end

#json_api_urlString

Returns the JSON API #call URL.

Returns:

  • (String)

    the JSON API #call URL



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

def json_api_url
  @json_api_url
end

#parsed_urlObject

Returns the value of attribute parsed_url.



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

def parsed_url
  @parsed_url
end

#uriMatchData

Returns the parsed URL.

Returns:

  • (MatchData)

    the parsed URL



28
# File 'lib/aspire/caching/cache_entry.rb', line 28

attr_accessor :parsed_url

#urlString

Returns the URL.

Returns:

  • (String)

    the URL



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

def url
  @url
end

Instance Method Details

#==(other) ⇒ Boolean

Returns true if cache entries refer to the same object

Parameters:

Returns:

  • (Boolean)

    true if the entries refer to the same object



48
49
50
# File 'lib/aspire/caching/cache_entry.rb', line 48

def ==(other)
  url == url_for_comparison(other, cache.ld_api)
end

#cached?(json = false) ⇒ Boolean

Returns true if the object is in the cache, false if not

Returns:

  • (Boolean)

    true if the object is cached, false if not



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

def cached?(json = false)
  filename = json ? json_file : file
  filename.nil? ? nil : File.exist?(filename)
end

#child_of?(url, strict: false) ⇒ Boolean

Returns true if this cache entry is a child of the URL

Parameters:

  • url (Aspire::Caching::CacheEntry, String)

    the URL to test

  • strict (Boolean) (defaults to: false)

    if true, the URL must be a parent of this entry, otherwise the URL must be a parent or the same as this entry

Returns:

  • (Boolean)

    true if the URL is a child of the cache entry, false otherwise



58
59
60
# File 'lib/aspire/caching/cache_entry.rb', line 58

def child_of?(url, strict: false)
  child_url?(parsed_url, url, cache.ld_api, strict: strict)
end

#delete(force: false, remove_children: false) ⇒ void

This method returns an undefined value.

Deletes the object from the cache

Parameters:

  • force (Boolean) (defaults to: false)

    delete even if the entry is marked in-progress

  • remove_children (Boolean) (defaults to: false)

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

Raises:



76
77
78
# File 'lib/aspire/caching/cache_entry.rb', line 76

def delete(force: false, remove_children: false)
  mark(force: force) { |_f| delete_entry(file, remove_children) }
end

#fileString

Returns the linked data filename in the cache

Returns:

  • (String)

    the linked data filename in the cache



82
83
84
# File 'lib/aspire/caching/cache_entry.rb', line 82

def file
  File.join(cache.path, url_path)
end

#json?Boolean

Returns true if the object has associated JSON API data, false if not

Returns:

  • (Boolean)

    true if the object has associated JSON API data, false otherwise



89
90
91
# File 'lib/aspire/caching/cache_entry.rb', line 89

def json?
  !json_api_url.nil? && !json_api_url.empty?
end

#json_file(filename = nil) ⇒ String?

Returns the JSON API data filename in the cache or nil if there is no JSON API data for the URL

Parameters:

  • filename (String) (defaults to: nil)

    the linked data filename in the cache

Returns:

  • (String, nil)

    the JSON API data filename or nil if there is no JSON API data for the URL



98
99
100
# File 'lib/aspire/caching/cache_entry.rb', line 98

def json_file(filename = nil)
  json? ? add_filename_suffix(filename || file, '-json') : nil
end

#list?(strict: true) ⇒ Boolean

Returns true if the cache entry is a list, false otherwise

Parameters:

  • strict (Boolean) (defaults to: true)

    if true, the cache entry must be a list, otherwise the cache entry must be a list or a child of a list

Returns:

  • (Boolean)

    true if the cache entry is a list, false otherwise



106
107
108
109
110
111
112
# File 'lib/aspire/caching/cache_entry.rb', line 106

def list?(strict: true)
  # The cache entry must be a list or the child of a list
  return false unless parsed_url[:type] == 'lists'
  # Strict checking requires that the cache entry is a list, not a child
  return false if strict && !parsed_url[:child_type].nil?
  true
end

#mark(force: false) {|file| ... } ⇒ void

This method returns an undefined value.

Marks the cache entry as in-progress

Parameters:

  • force (Boolean) (defaults to: false)

    if true, do not raise MarkedError when the entry is already marked; otherwise, MarkedError is raised when the entry is already marked.

Yields:

  • (file)

    passes the opened status file to the block

Yield Parameters:

  • file (File)

    the opened status file

Raises:



124
125
126
127
128
129
130
131
132
133
# File 'lib/aspire/caching/cache_entry.rb', line 124

def mark(force: false, &block)
  filename = status_file
  flags = File::CREAT
  flags |= File::EXCL unless force
  File.open(filename, flags, &block)
rescue Errno::EEXIST
  raise MarkedError, "#{url} already marked [#{filename}]"
rescue SystemCallError => e
  raise MarkError, "#{url} mark failed [#{filename}]: #{e}"
end

#marked?Boolean

Returns true if the cache entry is locked

Returns:

  • (Boolean)

    true if the cache entry is marked as in-progress, false otherwise



138
139
140
# File 'lib/aspire/caching/cache_entry.rb', line 138

def marked?
  File.exist?(status_file)
end

#parent_of?(url, strict: false) ⇒ Boolean

Returns true if this cache entry is the parent of the URL

Parameters:

  • url (Aspire::Caching::CacheEntry, String)

    the URL to test

  • strict (Boolean) (defaults to: false)

    if true, the URL must be a parent of this entry, otherwise the URL must be a parent or the same as this entry

Returns:

  • (Boolean)

    true if this cache entry is the parent of the URL, false otherwise



148
149
150
# File 'lib/aspire/caching/cache_entry.rb', line 148

def parent_of?(url, strict: false)
  parent_url?(parsed_url, url, cache.ld_api, strict: strict)
end

#path(json = false) ⇒ Object

Returns the filename of the cache entry

Parameters:

  • json (Boolean) (defaults to: false)

    if true, returns the JSON API filename, otherwise returns the linked data API filename



155
156
157
# File 'lib/aspire/caching/cache_entry.rb', line 155

def path(json = false)
  json ? json_file : file
end

#read(json = false, parsed: false) ⇒ Array, ...

Returns data from the cache

Parameters:

  • json (Boolean) (defaults to: false)

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

  • parsed (Boolean) (defaults to: false)

    if true, return JSON-parsed data, otherwise return a JSON string

Returns:

  • (Array, Hash, String, nil)

    the parsed JSON data or JSON string, or nil if JSON API data is requested but not available for this entry

Raises:



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/aspire/caching/cache_entry.rb', line 168

def read(json = false, parsed: false)
  filename = json ? json_file : file
  return nil if filename.nil? || filename.empty?
  File.open(filename, 'r') do |f|
    data = f.read
    return parsed ? JSON.parse(data) : data
  end
rescue Errno::ENOENT
  raise CacheMiss, "#{url} cache miss [#{filename}"
rescue IOError, SystemCallError => e
  raise ReadError, "#{url} cache read failed [#{filename}]: #{e}"
end

#references?Boolean

Returns true if the object’s references are cacheable

Returns:

  • (Boolean)

    true if the object’s references are cacheable, false otherwise



184
185
186
187
# File 'lib/aspire/caching/cache_entry.rb', line 184

def references?
  # Events are not JSON-LD so we can't cache references
  parsed_url[:type] != 'events' && parsed_url[:child_type] != 'events'
end

#status_file(filename = nil) ⇒ Object

Returns the status filename in the cache

Parameters:

  • filename (String) (defaults to: nil)

    the linked data filename in the cache



191
192
193
194
# File 'lib/aspire/caching/cache_entry.rb', line 191

def status_file(filename = nil)
  # Prepend '.' to the filename
  add_filename_prefix(filename || file, '.')
end

#to_sString

Returns a string representation of the cache entry

Returns:

  • (String)

    the string representation (URL) of the cache entry



198
199
200
# File 'lib/aspire/caching/cache_entry.rb', line 198

def to_s
  url
end

#unmarkObject

Removes an in-progress mark from the cache entry



203
204
205
206
207
208
# File 'lib/aspire/caching/cache_entry.rb', line 203

def unmark
  filename = status_file
  File.delete(filename) if File.exist?(filename)
rescue SystemCallError => e
  raise UnmarkError, "#{url} unmark failed [#{filename}]: #{e}"
end

#write(data, json = false, parsed: false) ⇒ void

This method returns an undefined value.

Writes data to the cache

Parameters:

  • data (Object)

    the data to write to the cache

  • json (Boolean) (defaults to: false)

    if true, write the data as JSON API data, otherwise write it as linked data

  • parsed (Boolean) (defaults to: false)

    if true, treat data as a parsed JSON data structure, otherwise treat it as a JSON string

Raises:



236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/aspire/caching/cache_entry.rb', line 236

def write(data, json = false, parsed: false)
  filename = json ? json_file : file
  return if filename.nil? || filename.empty?
  # Create the path to the file
  FileUtils.mkdir_p(File.dirname(filename), mode: cache.mode)
  # Write the data
  File.open(filename, 'w') do |f|
    f.flock(File::LOCK_EX)
    f.write(parsed ? JSON.generate(data) : data)
  end
rescue IOError, JSON::JSONError, SystemCallError => e
  raise WriteError, "#{url} cache write failed [#{filename}]: #{e}"
end