singleton-client 0.7.5 → 0.7.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|