Class: Xcflushd::Storage

Inherits:
Object
  • Object
show all
Defined in:
lib/xcflushd/storage.rb

Overview

The error handling could be improved to try to avoid losing reports However, there are trade-offs to be made. Complex error handling can complicate a lot the code. Also, there are no guarantees that the code in the rescue clauses will be executed correctly. For example, if an smembers operations fails because Redis is not accessible, and the error handling consists of performing other operations to Redis, the error handling could fail too. Some characteristics of Redis, like the absence of rollbacks limit the kind of things we can do in case of error. In the future, we might explore other options like lua scripts or keeping a journal (in Redis or disk).

Defined Under Namespace

Classes: RenewAuthError

Instance Method Summary collapse

Constructor Details

#initialize(storage, logger, storage_keys) ⇒ Storage

Returns a new instance of Storage.



40
41
42
43
44
# File 'lib/xcflushd/storage.rb', line 40

def initialize(storage, logger, storage_keys)
  @storage = storage
  @logger = logger
  @storage_keys = storage_keys
end

Instance Method Details

#renew_auths(service_id, credentials, authorizations, auth_ttl) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/xcflushd/storage.rb', line 73

def renew_auths(service_id, credentials, authorizations, auth_ttl)
  hash_key = hash_key(:auth, service_id, credentials)

  authorizations.each_slice(REDIS_BATCH_KEYS) do |authorizations_slice|
    # Array with the hash key and all the sorted key-values
    hmset_args = [hash_key]

    authorizations_slice.each do |metric, auth|
      hmset_args << metric
      hmset_args << auth_value(auth)
    end

    storage.hmset(*hmset_args)
  end

  set_auth_validity(service_id, credentials, auth_ttl)

rescue Redis::BaseError
  raise RenewAuthError.new(service_id, credentials)
end

#report(reports) ⇒ Object



94
95
96
97
98
99
# File 'lib/xcflushd/storage.rb', line 94

def report(reports)
  reports.each do |report|
    increase_usage(report)
    add_to_set_keys_cached_reports(report)
  end
end

#reports_to_flushObject

This performs a cleanup of the reports to be flushed. We can decide later whether it is better to leave this responsibility to the caller of the method.

Returns an array of hashes where each of them has a service_id, credentials, and a usage. The usage is another hash where the keys are the metrics and the values are guaranteed to respond to to_i and to_s.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/xcflushd/storage.rb', line 53

def reports_to_flush
  # The Redis rename command overwrites the key with the new name if it
  # exists. This means that if the rename operation fails in a flush cycle,
  # and succeeds in a next one, the data that the key had in the first
  # flush cycle will be lost.
  # For that reason, every time we need to rename a key, we will use a
  # unique suffix. This way, when the rename operation fails, the key
  # will not be overwritten later, and we will be able to recover its
  # content.
  suffix = suffix_for_unique_naming

  report_keys = report_keys_to_flush(suffix)
  if report_keys.empty?
    logger.warn "No reports available to flush"
    report_keys
  else
    reports(report_keys, suffix)
  end
end