singleton-client 0.7.5 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -28
- data/lib/sgtn-client/api/source.rb +7 -65
- data/lib/sgtn-client/api/t.rb +16 -17
- data/lib/sgtn-client/api/translation.rb +77 -122
- data/lib/sgtn-client/cldr/localized_str.rb +1 -0
- data/lib/sgtn-client/common/data.rb +30 -0
- data/lib/sgtn-client/common/single_operation.rb +34 -0
- data/lib/sgtn-client/core/cache.rb +12 -81
- data/lib/sgtn-client/core/config.rb +38 -2
- data/lib/sgtn-client/exceptions.rb +6 -0
- data/lib/sgtn-client/loader/cache.rb +71 -0
- data/lib/sgtn-client/loader/chain_loader.rb +49 -0
- data/lib/sgtn-client/loader/consts.rb +15 -0
- data/lib/sgtn-client/loader/loader_factory.rb +33 -0
- data/lib/sgtn-client/loader/local_translation.rb +49 -0
- data/lib/sgtn-client/loader/server.rb +94 -0
- data/lib/sgtn-client/loader/single_loader.rb +48 -0
- data/lib/sgtn-client/loader/source.rb +56 -0
- data/lib/sgtn-client/loader/source_comparer.rb +58 -0
- data/lib/sgtn-client/sgtn-client.rb +2 -0
- data/lib/sgtn-client/util/cache-util.rb +30 -38
- data/lib/sgtn-client/util/locale-util.rb +62 -38
- data/lib/sgtn-client/util/string-util.rb +12 -0
- data/lib/sgtn-client/util/validate-util.rb +1 -6
- data/lib/singleton-client.rb +15 -0
- data/lib/singleton-ruby.rb +2 -0
- metadata +43 -147
- data/lib/sgtn-client/core/request.rb +0 -24
- data/lib/sgtn-client/util/file-util.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a587958936d82290e3937f0a96097f4254bb3e8743673a808702a2881d414ff9
|
4
|
+
data.tar.gz: f60706e62d08f058fca8eb1b286800f61f4a79f78cd5aadb4b1c53ed7736f62f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f89add299ebf85604d748fdc5c3d4e0fed05f98810514ca4de8b23eb3305af0568c32d308b59fa2b54f1f3188531de4c07732d6d5c59d4d13cc3a6f6ef0cb21
|
7
|
+
data.tar.gz: c2192d0d69ed16250d55a5f9e255c4ede49b404cc93f90ae3d266aa1663cdfcdce114317b593509a8be64e0f6d3587811eb4f8587b39517c08a5647460a462d1
|
data/README.md
CHANGED
@@ -1,54 +1,53 @@
|
|
1
|
-
#
|
1
|
+
# Singleton Client for Ruby
|
2
2
|
|
3
3
|
## Prerequisites
|
4
4
|
- Ruby version: 3.0.0 or above
|
5
5
|
- Bundler version: 2.2.3 or above
|
6
6
|
|
7
7
|
## Run Unit Test
|
8
|
-
rake spec
|
8
|
+
`rake spec`
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
12
|
Basic Usage:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
require 'singleton-
|
16
|
-
|
17
|
-
include SgtnClient
|
18
|
-
|
19
|
-
SgtnClient.load(file, mode)
|
20
|
-
|
21
|
-
SgtnClient::Source.loadBundles(locale)
|
22
|
-
|
23
|
-
@Result = SgtnClient::Translation.getString(component, key, locale)
|
15
|
+
require 'singleton-client'
|
24
16
|
|
17
|
+
Sgtn.load_config(file, env)
|
18
|
+
result = Sgtn.translate(key, component, locale)
|
25
19
|
```
|
26
20
|
## API Usage
|
27
21
|
|
28
22
|
### Get a string's translation
|
29
|
-
|
30
|
-
|
31
|
-
### Get a string's translation and format it with placeholders
|
32
|
-
SgtnClient::Translation.getString_f(component, key, args, locale)
|
33
|
-
|
34
|
-
### Get a component's translations
|
35
|
-
SgtnClient::Translation.getStrings(component, locale)
|
36
|
-
|
23
|
+
`result = Sgtn.translate(key, component, locale)`
|
37
24
|
|
38
|
-
|
39
|
-
|
40
|
-
Before call below APIs(without locale and component arguments), it requires to set the locale and component in the initial codes.
|
41
|
-
|
42
|
-
### Get a string's translation
|
43
|
-
SgtnClient::T.s(key)
|
25
|
+
### Get a string's translation with default value when no translation
|
26
|
+
`result = Sgtn.translate(key, component, locale) { 'default value' }`
|
44
27
|
|
45
28
|
### Get a string's translation and format it with placeholders
|
46
|
-
|
29
|
+
`result = Sgtn.translate(key, component, locale, **args)`
|
47
30
|
|
48
|
-
### Get
|
49
|
-
|
31
|
+
### Get pluralized translation
|
32
|
+
`result = Sgtn.translate(key, component, locale, **args)`
|
50
33
|
|
34
|
+
### Get translations of a bundle
|
35
|
+
`result = Sgtn.get_translations(component, locale)`
|
51
36
|
|
37
|
+
### Set locale for a request
|
38
|
+
`Sgtn.locale = 'en'`
|
52
39
|
|
40
|
+
### Get locale of the request
|
41
|
+
`result = Sgtn.locale`
|
53
42
|
|
43
|
+
### Get a string's translation with locale set
|
44
|
+
```ruby
|
45
|
+
Sgtn.locale = 'en'
|
46
|
+
result = Sgtn.translate(key, component)
|
47
|
+
```
|
54
48
|
|
49
|
+
### Get translations of a bundle with locale set
|
50
|
+
```ruby
|
51
|
+
Sgtn.locale = 'en'
|
52
|
+
result = Sgtn.get_translations(component)
|
53
|
+
```
|
@@ -1,73 +1,15 @@
|
|
1
1
|
# Copyright 2022 VMware, Inc.
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
|
+
require 'sgtn-client/loader/source'
|
5
|
+
|
4
6
|
module SgtnClient
|
5
|
-
|
6
|
-
autoload :CacheUtil, "sgtn-client/util/cache-util"
|
7
|
+
autoload :CacheUtil, 'sgtn-client/util/cache-util'
|
7
8
|
|
8
9
|
class Source
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
14
|
-
if items.nil?
|
15
|
-
items = getBundle(component, locale)
|
16
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
17
|
-
else
|
18
|
-
SgtnClient.logger.debug "[Source][getSource]getting sources from cache with key: " + cache_key
|
19
|
-
end
|
20
|
-
s = (items.nil? || items[locale].nil?)? nil : items[locale][key]
|
21
|
-
if items.nil? || s.nil?
|
22
|
-
SgtnClient.logger.debug "[Source][getSource]source not found, return key: " + key
|
23
|
-
#return key
|
24
|
-
return nil
|
25
|
-
else
|
26
|
-
return s
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.getSources(component, locale)
|
31
|
-
SgtnClient.logger.debug "[Source][getSources]component=#{component}, locale=#{locale}"
|
32
|
-
cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
33
|
-
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
34
|
-
if items.nil? || expired
|
35
|
-
items = getBundle(component, locale)
|
36
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
37
|
-
else
|
38
|
-
SgtnClient.logger.debug "[Source][getSources]getting sources from cache with key: " + cache_key
|
39
|
-
end
|
40
|
-
return items
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.loadBundles(locale)
|
44
|
-
SgtnClient.logger.debug "[Source][loadBundles]locale=#{locale}"
|
45
|
-
env = SgtnClient::Config.default_environment
|
46
|
-
SgtnClient::Config.configurations.default = locale
|
47
|
-
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
48
|
-
Dir.foreach(source_bundle) do |component|
|
49
|
-
next if component == '.' || component == '..'
|
50
|
-
yamlfile = File.join(source_bundle, component + "/" + locale + ".yml")
|
51
|
-
bundle = SgtnClient::FileUtil.read_yml(yamlfile)
|
52
|
-
cachekey = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
53
|
-
SgtnClient::CacheUtil.write_cache(cachekey,bundle)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
def self.getBundle(component, locale)
|
59
|
-
SgtnClient.logger.debug "[Source][getBundle]component=#{component}, locale=#{locale}"
|
60
|
-
env = SgtnClient::Config.default_environment
|
61
|
-
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
62
|
-
bundlepath = source_bundle + "/" + component + "/" + locale + ".yml"
|
63
|
-
begin
|
64
|
-
bundle = SgtnClient::FileUtil.read_yml(bundlepath)
|
65
|
-
rescue => exception
|
66
|
-
SgtnClient.logger.error exception.message
|
67
|
-
end
|
68
|
-
return bundle
|
69
|
-
end
|
70
|
-
|
10
|
+
def self.loadBundles(locale)
|
11
|
+
SgtnClient.logger.debug "[Source][loadBundles]locale=#{locale}"
|
12
|
+
SgtnClient::Config.configurations.default = locale
|
13
|
+
end
|
71
14
|
end
|
72
|
-
|
73
15
|
end
|
data/lib/sgtn-client/api/t.rb
CHANGED
@@ -2,24 +2,23 @@
|
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
4
|
module SgtnClient
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
5
|
+
class T
|
6
|
+
def self.s(key)
|
7
|
+
locale = RequestStore.store[:locale]
|
8
|
+
component = RequestStore.store[:component]
|
9
|
+
Translation.getString(component, key, locale)
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def self.s_f(key, args)
|
13
|
+
locale = RequestStore.store[:locale]
|
14
|
+
component = RequestStore.store[:component]
|
15
|
+
Translation.getString_f(component, key, args, locale)
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
18
|
+
def self.c
|
19
|
+
locale = RequestStore.store[:locale]
|
20
|
+
component = RequestStore.store[:component]
|
21
|
+
Translation.getStrings(component, locale)
|
24
22
|
end
|
23
|
+
end
|
25
24
|
end
|
@@ -1,158 +1,113 @@
|
|
1
1
|
# Copyright 2022 VMware, Inc.
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
|
-
require '
|
4
|
+
require 'request_store'
|
5
5
|
|
6
6
|
module SgtnClient
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
autoload :CacheUtil, "sgtn-client/util/cache-util"
|
12
|
-
autoload :LocaleUtil, "sgtn-client/util/locale-util"
|
13
|
-
end
|
14
|
-
|
15
|
-
class Translation
|
16
|
-
|
17
|
-
def self.getString(component, key, locale)
|
7
|
+
module Translation
|
8
|
+
module Implementation
|
9
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
10
|
+
def getString(component, key, locale)
|
18
11
|
SgtnClient.logger.debug "[Translation.getString]component: #{component}, key: #{key}, locale: #{locale}"
|
19
|
-
|
20
|
-
if str.nil?
|
21
|
-
str = SgtnClient::Source.getSource(component, key, SgtnClient::Config.configurations.default)
|
22
|
-
if str.nil?
|
23
|
-
SgtnClient.logger.debug "[Translation][getString] Missing source string with key: #{key}, component: #{component}, locale: #{locale}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
str
|
12
|
+
translate(key, component, locale) { nil }
|
27
13
|
end
|
28
14
|
|
29
|
-
|
15
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
16
|
+
def getString_p(component, key, plural_args, locale)
|
30
17
|
SgtnClient.logger.debug "[Translation][getString_p]component=#{component}, key=#{key}, locale=#{locale}"
|
31
|
-
|
32
|
-
if str.nil?
|
33
|
-
str = SgtnClient::Source.getSource(component, key, SgtnClient::Config.configurations.default)
|
34
|
-
if str.nil?
|
35
|
-
SgtnClient.logger.debug "[Translation][getString_p] Missing source string with key: #{key}, component: #{component}, locale: #{locale}"
|
36
|
-
return nil
|
37
|
-
end
|
38
|
-
str.to_plural_s(:en, plural_args)
|
39
|
-
else
|
40
|
-
str.to_plural_s(locale, plural_args)
|
41
|
-
end
|
18
|
+
translate(key, component, locale, **plural_args) { nil }
|
42
19
|
end
|
43
20
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
21
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
22
|
+
def getString_f(component, key, args, locale, *_optionals)
|
23
|
+
SgtnClient.logger.debug "[Translation][getString_f]component=#{component}, key=#{key}, locale=#{locale}"
|
24
|
+
s = translate(key, component, locale) { nil }
|
25
|
+
return nil if s.nil?
|
26
|
+
|
27
|
+
if args.is_a?(Hash)
|
51
28
|
args.each do |source, arg|
|
52
29
|
s.gsub! "{#{source}}", arg
|
53
30
|
end
|
54
|
-
|
55
|
-
s =
|
56
|
-
|
57
|
-
|
31
|
+
elsif args.is_a?(Array)
|
32
|
+
s = s % args
|
33
|
+
end
|
34
|
+
s
|
58
35
|
end
|
59
36
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
default = SgtnClient::Config.configurations.default
|
65
|
-
if items.nil? || items["messages"] == nil
|
66
|
-
items = {}
|
67
|
-
s = SgtnClient::Source.getSources(component, default)
|
68
|
-
if s.nil?
|
69
|
-
SgtnClient.logger.error "[Translation][getStrings] Missing component: #{component}, locale: #{locale}"
|
70
|
-
else
|
71
|
-
default_component, value = s.first
|
72
|
-
items["component"] = component
|
73
|
-
items["messages"] = value
|
74
|
-
items["locale"] = 'source'
|
75
|
-
end
|
76
|
-
end
|
77
|
-
return items
|
78
|
-
end
|
37
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:get_translations</tt> instead.
|
38
|
+
def getStrings(component, locale)
|
39
|
+
get_translations(component, locale)
|
40
|
+
end
|
79
41
|
|
42
|
+
# raise error when translation is not found
|
43
|
+
def translate(key, component, locale = nil, **kwargs)
|
44
|
+
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] key: #{key}, component: #{component}, locale: #{locale}, args: #{kwargs}"
|
80
45
|
|
81
|
-
|
46
|
+
locale = locale.nil? ? self.locale : SgtnClient::LocaleUtil.get_best_locale(locale)
|
82
47
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
nil
|
88
|
-
else
|
89
|
-
items["messages"][key]
|
48
|
+
result = get_bundle(component, locale)&.fetch(key, nil)
|
49
|
+
if result.nil? && !LocaleUtil.is_source_locale(locale)
|
50
|
+
locale = LocaleUtil.get_source_locale
|
51
|
+
result = get_bundle(component, locale)&.fetch(key, nil)
|
90
52
|
end
|
91
|
-
end
|
92
53
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
return {'locale' => locale, 'component' => component, 'messages' => messages} if messages
|
54
|
+
if result.nil?
|
55
|
+
return key unless block_given?
|
56
|
+
|
57
|
+
result = yield
|
58
|
+
return if result.nil?
|
99
59
|
end
|
100
60
|
|
101
|
-
|
102
|
-
|
103
|
-
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
104
|
-
if items.nil? || expired
|
105
|
-
items = load(component, locale)
|
106
|
-
if items.nil?
|
107
|
-
items = SgtnClient::Source.getSources(component, SgtnClient::Config.configurations.default)
|
108
|
-
SgtnClient::Core::Cache.put(cache_key, items, 60)
|
109
|
-
else
|
110
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
111
|
-
end
|
61
|
+
if kwargs.empty?
|
62
|
+
result
|
112
63
|
else
|
113
|
-
|
64
|
+
locale = result.locale if result.is_a?(SgtnClient::StringUtil)
|
65
|
+
result.localize(locale) % kwargs
|
114
66
|
end
|
67
|
+
end
|
68
|
+
alias t translate
|
115
69
|
|
116
|
-
|
117
|
-
|
70
|
+
def get_translations(component, locale = nil)
|
71
|
+
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component: #{component}, locale: #{locale}"
|
118
72
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
return load_o(component, locale)
|
125
|
-
else
|
126
|
-
return load_s(component, locale)
|
73
|
+
locale = locale.nil? ? self.locale : SgtnClient::LocaleUtil.get_best_locale(locale)
|
74
|
+
items = get_bundle(component, locale)
|
75
|
+
if items.nil? && !LocaleUtil.is_source_locale(locale)
|
76
|
+
items = get_bundle(component, LocaleUtil.get_source_locale)
|
77
|
+
locale = LocaleUtil.get_source_locale
|
127
78
|
end
|
79
|
+
|
80
|
+
{ 'component' => component, 'locale' => locale, 'messages' => items || {} } if items
|
128
81
|
end
|
129
82
|
|
130
|
-
def
|
131
|
-
|
132
|
-
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
133
|
-
version = SgtnClient::Config.configurations[env]["version"].to_s
|
134
|
-
translation_bundle = SgtnClient::Config.configurations[env]["translation_bundle"]
|
135
|
-
bundlepath = translation_bundle + "/" + product_name + "/" + version + "/" + component + "/messages_" + locale + ".json"
|
136
|
-
SgtnClient::FileUtil.read_json(bundlepath)
|
83
|
+
def locale
|
84
|
+
RequestStore.store[:locale] ||= SgtnClient::LocaleUtil.get_fallback_locale
|
137
85
|
end
|
138
86
|
|
139
|
-
def
|
140
|
-
|
141
|
-
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
142
|
-
vip_server = SgtnClient::Config.configurations[env]["vip_server"]
|
143
|
-
version = SgtnClient::Config.configurations[env]["version"].to_s
|
144
|
-
url = vip_server + "/i18n/api/v2/translation/products/" + product_name + "/versions/" + version + "/locales/" + locale + "/components/" + component+ "?checkTranslationStatus=false&machineTranslation=false&pseudo=false"
|
145
|
-
begin
|
146
|
-
obj = SgtnClient::Core::Request.get(url)
|
147
|
-
rescue => exception
|
148
|
-
SgtnClient.logger.error exception.message
|
149
|
-
end
|
150
|
-
if obj != nil
|
151
|
-
obj = obj["data"]
|
152
|
-
end
|
153
|
-
return obj
|
87
|
+
def locale=(value)
|
88
|
+
RequestStore.store[:locale] = SgtnClient::LocaleUtil.get_best_locale(value)
|
154
89
|
end
|
155
90
|
|
156
|
-
|
91
|
+
private
|
92
|
+
|
93
|
+
def get_bundle(component, locale)
|
94
|
+
get_bundle!(component, locale)
|
95
|
+
rescue StandardError => e
|
96
|
+
SgtnClient.logger.error "[#{method(__callee__).owner}.#{__callee__}] failed to get a bundle. component: #{component}, locale: #{locale}"
|
97
|
+
SgtnClient.logger.error e
|
98
|
+
nil
|
99
|
+
end
|
157
100
|
|
101
|
+
def get_bundle!(component, locale)
|
102
|
+
id = SgtnClient::Common::BundleID.new(component, locale)
|
103
|
+
bundles = SgtnClient::Config.available_bundles
|
104
|
+
unless bundles.nil? || bundles.empty? || bundles.include?(id)
|
105
|
+
raise SgtnClient::SingletonError, 'bundle is unavailable.'
|
106
|
+
end
|
107
|
+
|
108
|
+
SgtnClient::Config.loader.get_bundle(component, locale)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
extend Implementation
|
112
|
+
end
|
158
113
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
4
|
String.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
5
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
5
6
|
def to_plural_s(locale, arg)
|
6
7
|
num_str = SgtnClient::Formatters::PluralFormatter.new(locale).num_s(self, arg)
|
7
8
|
if num_str.nil? || num_str.empty?
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
module Common
|
6
|
+
class BundleID
|
7
|
+
attr_reader :locale, :component
|
8
|
+
|
9
|
+
def initialize(component, locale)
|
10
|
+
@locale = locale
|
11
|
+
@component = component
|
12
|
+
@key = [@component, @locale].hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def hash
|
16
|
+
@key
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
(other.is_a? self.class) && @locale == other.locale && @component == other.component
|
21
|
+
end
|
22
|
+
|
23
|
+
alias eql? ==
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"locale=#{@locale}, component=#{@component}}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
class SingleOperation
|
6
|
+
def initialize(*conditions, &block)
|
7
|
+
raise 'no way to create a new obj' unless block
|
8
|
+
|
9
|
+
@lock = Mutex.new
|
10
|
+
@hash = {}
|
11
|
+
|
12
|
+
@conditions = conditions
|
13
|
+
@creator = block
|
14
|
+
end
|
15
|
+
|
16
|
+
# return new created object
|
17
|
+
def operate(id, *args)
|
18
|
+
@lock.synchronize do
|
19
|
+
obj = @hash[id]
|
20
|
+
@conditions.each do |con|
|
21
|
+
return obj unless con.call(id, obj, *args)
|
22
|
+
end
|
23
|
+
# TODO: whatif returning nil
|
24
|
+
@hash[id] = @creator.call(id, obj, *args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove_object(id)
|
29
|
+
@lock.synchronize do
|
30
|
+
@hash.delete(id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -5,99 +5,30 @@ require 'date'
|
|
5
5
|
|
6
6
|
module SgtnClient::Core
|
7
7
|
class Cache
|
8
|
-
Entry = Struct.new(:expiry, :
|
8
|
+
Entry = Struct.new(:expiry, :items)
|
9
9
|
|
10
10
|
def self.initialize(disabled=false, opts={})
|
11
11
|
@@opts = opts
|
12
|
-
|
13
|
-
|
14
|
-
@@data = Hash.new
|
15
|
-
SgtnClient.logger.debug "[Cache][initialize]cache is enabled!"
|
16
|
-
else
|
17
|
-
@@data = nil
|
18
|
-
SgtnClient.logger.debug "[Cache][initialize]cache is disabled!"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.keys
|
23
|
-
if @@data == nil
|
24
|
-
return nil
|
25
|
-
end
|
26
|
-
SgtnClient.logger.debug "[Cache][keys]get cache keys"
|
27
|
-
@@data.keys
|
12
|
+
SgtnClient.logger.debug "[Cache][initialize] Disable cache? #{disabled}"
|
13
|
+
@@data = Hash.new
|
28
14
|
end
|
29
15
|
|
30
16
|
def self.get(key)
|
31
|
-
if @@data == nil
|
32
|
-
return nil, nil
|
33
|
-
end
|
34
17
|
SgtnClient.logger.debug "[Cache][get]get cache for key: " + key
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.has(key)
|
39
|
-
if @@data == nil
|
40
|
-
return nil
|
41
|
-
end
|
42
|
-
SgtnClient.logger.debug "[Cache][has]check if the cache has key: #{(@@data.has_key? key)}"
|
43
|
-
@@data.has_key? key
|
18
|
+
return @@data&.dig(key)
|
44
19
|
end
|
45
20
|
|
46
|
-
def self.put(key,
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
ttl ||= @@opts[:ttl]
|
52
|
-
# hours from new
|
53
|
-
SgtnClient.logger.debug "[Cache][put]put cache for key '" + key + "' with expired time at'" + (Time.now + ttl*60).to_s
|
54
|
-
@@data[key] = Entry.new(Time.now + ttl*60, value)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.delete(key)
|
59
|
-
@mutex.synchronize do
|
60
|
-
if @@data == nil
|
61
|
-
return nil
|
62
|
-
end
|
63
|
-
SgtnClient.logger.debug "[Cache][delete]delete cache for key: " + key
|
64
|
-
@@data.delete key
|
65
|
-
end
|
21
|
+
def self.put(key, items, ttl=nil)
|
22
|
+
ttl ||= @@opts[:ttl]
|
23
|
+
# hours from new
|
24
|
+
SgtnClient.logger.debug "[Cache][put]put cache for key '" + key + "' with expired time at'" + (Time.now + ttl*60).to_s
|
25
|
+
@@data[key] = Entry.new(Time.now + ttl*60, items)
|
66
26
|
end
|
67
27
|
|
68
28
|
def self.clear
|
69
|
-
|
70
|
-
|
71
|
-
return nil
|
72
|
-
end
|
73
|
-
SgtnClient.logger.debug "[Cache][clear]clear cache!"
|
74
|
-
@@data = Hash.new
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.invalidate(key)
|
79
|
-
@mutex.synchronize do
|
80
|
-
if @@data == nil
|
81
|
-
return nil, nil
|
82
|
-
end
|
83
|
-
SgtnClient.logger.debug "[Cache][invalidate]invalidate expired cache......"
|
84
|
-
now = Time.now
|
85
|
-
if has(key)
|
86
|
-
v = @@data[key]
|
87
|
-
expired = false
|
88
|
-
SgtnClient.logger.debug "[Cache][invalidate]check cache: key=#{key}, expiredtime=#{v[:expiry]}, now=#{now}, expired=#{(v[:expiry] < now)}"
|
89
|
-
if v[:expiry] < now
|
90
|
-
SgtnClient.logger.debug "[Cache][invalidate]before deleting the cache: data=#{@@data}"
|
91
|
-
@@data.delete(key)
|
92
|
-
SgtnClient.logger.debug "[Cache][invalidate]after deleting the cache: data=#{@@data}"
|
93
|
-
expired = true
|
94
|
-
end
|
95
|
-
return expired, v[:value]
|
96
|
-
else
|
97
|
-
return nil, nil
|
98
|
-
end
|
99
|
-
end
|
29
|
+
SgtnClient.logger.debug "[Cache][clear]clear cache!"
|
30
|
+
@@data = Hash.new
|
100
31
|
end
|
101
32
|
end
|
102
33
|
|
103
|
-
end
|
34
|
+
end
|