Class: CopyTunerClient::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/copy_tuner_client/cache.rb

Overview

Manages synchronization of copy between I18nBackend and Client. Acts like a Hash. Applications using the client will not need to interact with this class directly.

Responsible for locking down access to data used by both threads.

Constant Summary collapse

STATUS_NOT_READY =
:not_ready
STATUS_PENDING =
:pending
STATUS_READY =
:ready

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, options) ⇒ Cache

Usually instantiated when CopyTunerClient::Configuration#apply is invoked.

Parameters:

  • client (Client)

    the client used to fetch and upload data

  • options (Hash)

Options Hash (options):

  • :logger (Logger)

    where errors should be logged



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/copy_tuner_client/cache.rb', line 19

def initialize(client, options)
  @client = client
  @logger = options[:logger]
  @mutex = Mutex.new
  @exclude_key_regexp = options[:exclude_key_regexp]
  @upload_disabled = options[:upload_disabled]
  @ignored_keys = options.fetch(:ignored_keys, [])
  @ignored_key_handler = options.fetch(:ignored_key_handler, -> (e) { raise e })
  @locales = Array(options[:locales]).map(&:to_s)
  # mutable states
  @blurbs = {}
  @blank_keys = Set.new
  @queued = {}
  @status = STATUS_NOT_READY
end

Instance Attribute Details

#blurbsObject (readonly)

Returns the value of attribute blurbs.



142
143
144
# File 'lib/copy_tuner_client/cache.rb', line 142

def blurbs
  @blurbs
end

#last_downloaded_atObject (readonly)

Returns the value of attribute last_downloaded_at.



142
143
144
# File 'lib/copy_tuner_client/cache.rb', line 142

def last_downloaded_at
  @last_downloaded_at
end

#last_uploaded_atObject (readonly)

Returns the value of attribute last_uploaded_at.



142
143
144
# File 'lib/copy_tuner_client/cache.rb', line 142

def last_uploaded_at
  @last_uploaded_at
end

#queuedObject (readonly)

Returns the value of attribute queued.



142
143
144
# File 'lib/copy_tuner_client/cache.rb', line 142

def queued
  @queued
end

Instance Method Details

#[](key) ⇒ String

Returns content for the given blurb.

Parameters:

  • key (String)

    the key of the desired blurb

Returns:

  • (String)

    the contents of the blurb



38
39
40
# File 'lib/copy_tuner_client/cache.rb', line 38

def [](key)
  lock { @blurbs[key] }
end

#[]=(key, value) ⇒ Object

Sets content for the given blurb. The content will be pushed to the server on the next flush.

Parameters:

  • key (String)

    the key of the blurb to update

  • value (String)

    the new contents of the blurb



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/copy_tuner_client/cache.rb', line 46

def []=(key, value)
  return if @exclude_key_regexp && key.match?(@exclude_key_regexp)
  return unless key.include?('.')
  return if @locales.present? && !@locales.member?(key.split('.').first)
  return if @upload_disabled

  # NOTE: config/locales以下のファイルに除外キーが残っていた場合の対応
  key_without_locale = key.split('.')[1..].join('.')
  if @ignored_keys.include?(key_without_locale)
    @ignored_key_handler.call(IgnoredKey.new("Ignored key: #{key_without_locale}"))
  end

  lock do
    return if @blank_keys.member?(key) || @blurbs.key?(key)

    @queued[key] = value
  end
end

#downloadObject



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/copy_tuner_client/cache.rb', line 116

def download
  @status = STATUS_PENDING unless ready?

  res = client.download(cache_fallback: pending?) do |downloaded_blurbs|
    blank_blurbs, blurbs = downloaded_blurbs.partition { |_key, value| value == '' }
    lock do
      @blank_keys = Set.new(blank_blurbs.map(&:first))
      @blurbs = blurbs.to_h
    end
  end

  @last_downloaded_at = Time.now.utc
  @status = STATUS_READY unless ready?

  res
rescue ConnectionError => e
  logger.error e.message
  raise e unless ready?
end

#exportString

Yaml representation of all blurbs

Returns:

  • (String)

    yaml



73
74
75
76
# File 'lib/copy_tuner_client/cache.rb', line 73

def export
  tree_hash = to_tree_hash
  tree_hash.present? ? tree_hash.to_yaml : nil
end

#flushObject



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/copy_tuner_client/cache.rb', line 104

def flush
  res = with_queued_changes do |queued|
    client.upload queued
  end

  @last_uploaded_at = Time.now.utc

  res
rescue ConnectionError => e
  logger.error e.message
end

#inspectObject



144
145
146
# File 'lib/copy_tuner_client/cache.rb', line 144

def inspect
  "#<CopyTunerClient::Cache:#{object_id}>"
end

#keysArray<String>

Keys for all blurbs stored on the server.

Returns:

  • (Array<String>)

    keys



67
68
69
# File 'lib/copy_tuner_client/cache.rb', line 67

def keys
  lock { @blurbs.keys }
end

#pending?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/copy_tuner_client/cache.rb', line 148

def pending?
  @status == STATUS_PENDING
end

#ready?Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/copy_tuner_client/cache.rb', line 152

def ready?
  @status == STATUS_READY
end

#syncObject

Downloads and then flushes



137
138
139
140
# File 'lib/copy_tuner_client/cache.rb', line 137

def sync
  download
  flush
end

#to_tree_hashHash

ツリー構造のハッシュを返す(I18nBackend用)

Returns:

  • (Hash)

    ツリー構造に変換されたblurbs



80
81
82
# File 'lib/copy_tuner_client/cache.rb', line 80

def to_tree_hash
  lock { @blurbs.present? ? DottedHash.to_h(@blurbs) : {} }
end

#versionString?

キャッシュの更新バージョンを返す(ツリーキャッシュの無効化判定用)ETags を使用してサーバーサイドの更新を検知

Returns:

  • (String, nil)

    現在のETag値



87
88
89
# File 'lib/copy_tuner_client/cache.rb', line 87

def version
  client.etag
end

#wait_for_downloadObject

Waits until the first download has finished.



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/copy_tuner_client/cache.rb', line 92

def wait_for_download
  return unless pending?

  logger.info 'Waiting for first download'

  if logger.respond_to? :flush
    logger.flush
  end

  sleep 0.1 while pending?
end