naranya_ecm-sdk 0.0.43 → 0.0.44

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 183c574009558b2788b71cce8899e52e9a948344
4
- data.tar.gz: d1ffcd41db7e78e43251c7714c7e7ec686223b15
3
+ metadata.gz: 2dc8adf4cc4abab1676463cd4c3c6075793c45c0
4
+ data.tar.gz: 4cc18d8ae9c0191a4b574454027dfb553f486040
5
5
  SHA512:
6
- metadata.gz: c010113401ef577a7b24a41e50614c4d98c77c91eba374f421279e224aa2529fac258423b9e2d19f00451d7950a7dad90f8a7e209f2dee6ddc230a6a60dae6e7
7
- data.tar.gz: 5fd603773082dbcd115d97e36b1ab9f68649c3ae3bd81b1e717ea43b32f87389fdda26188de350378337c133ebd2511fea3560c9cf6e49de44b4965521f90d70
6
+ metadata.gz: abc347b3b30e4ff20d0f2899b3420e4f8d5e0155453dc9bca2402061635d5b868443a7a3bbdf7cda0827e930c1db3893bc806bdf84f449445f54e003bf881472
7
+ data.tar.gz: eec0f1877d9e19da52d4de1e04357dfe3c4833a0f584c73176555cb37e3d7072bb6a28889b4b8f841dd8617ccb70ceda8b915bc852961291a7d0c70ed03c5ee7
@@ -0,0 +1,23 @@
1
+ NContent::SDK.logger.level = Logger::INFO
2
+ # Launch n threads:
3
+ 10.times.map do |i|
4
+ sleep 0.3
5
+
6
+ Thread.new do
7
+
8
+ 10.times.map do |reqno|
9
+ a = NaranyaEcm::Category.find "53367aa33535660003000000"
10
+ sleep 5
11
+ end
12
+
13
+ end
14
+ end.each(&:join)
15
+
16
+ puts "\nFinished!"
17
+ puts "\nFinished!"
18
+ puts "\nFinished!"
19
+ puts "\nFinished!"
20
+ puts "\nFinished!"
21
+ puts "\nFinished!"
22
+
23
+ NContent::SDK.logger.level = Logger::DEBUG
@@ -1,3 +1,3 @@
1
1
  module NaranyaEcm
2
- VERSION = "0.0.43"
2
+ VERSION = "0.0.44"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'oauth2'
2
2
  require 'ncontent/sdk/faraday_middleware'
3
+ require 'singleton'
3
4
 
4
5
  module NContent
5
6
 
@@ -7,22 +8,14 @@ module NContent
7
8
 
8
9
  class RESTClient
9
10
 
11
+ include Singleton
12
+
10
13
  CLIENT_TOKEN_CACHE_KEY = "ncontent/api_client/client_token".freeze
11
14
 
12
- class << self
13
- delegate :config, :logger, :cache, to: NContent::SDK
14
- end
15
+ delegate :config, :logger, :cache, to: NContent::SDK
15
16
 
16
- # Returns the thread's OAuth2 client instance.
17
- #
18
- # In multi-thread environments, each thread will have it's own client
19
- # instance object - since it's saved as a @instance_variable - but
20
- # shouldn't be a problem since the mutable data is actually the
21
- # client_token (see self.client_token).
22
- def self.instance
23
- @instance ||= OAuth2::Client.new(
24
- config.api_key, config.api_secret, site: config.api_host
25
- ) do |faraday|
17
+ def initialize
18
+ @client = OAuth2::Client.new(config.api_key, config.api_secret, site: config.api_host) do |faraday|
26
19
  ### Oauth2 Client (Faraday) builder:
27
20
 
28
21
  faraday.request :url_encoded # them posts...
@@ -39,33 +32,24 @@ module NContent
39
32
  faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
40
33
  end
41
34
  end
35
+ @client_token = get_token
36
+ @mutex = Mutex.new
42
37
  end
43
38
 
44
- # Returns a client_token initialized from cache.
45
- #
46
- # In multi-thread environments, each thread will have it's own
47
- # client_token object - since it's saved as a @instance_variable -, but
48
- # all of them should have the same token data - since it's initialized
49
- # from cache (We're assuming a thread-safe cache such as redis gem).
50
- def self.client_token
51
- @client_token ||= begin
52
- cached_token_data = cache.read CLIENT_TOKEN_CACHE_KEY
53
- if cached_token_data.present?
54
- OAuth2::AccessToken.from_hash instance, cached_token_data
39
+ def reset_client_token!
40
+ with_mutex do
41
+ if cached = cache.read(CLIENT_TOKEN_CACHE_KEY) and cached['access_token'] == @client_token.token
42
+ logger.debug "Deleting cache key #{CLIENT_TOKEN_CACHE_KEY}"
43
+ cache.delete CLIENT_TOKEN_CACHE_KEY
55
44
  else
56
- new_token = instance.client_credentials.get_token
57
- cache.write CLIENT_TOKEN_CACHE_KEY, new_token.to_hash
58
- new_token
45
+ logger.debug "Not deleting cache key #{CLIENT_TOKEN_CACHE_KEY}"
59
46
  end
47
+ @client_token = get_token
60
48
  end
61
49
  end
62
50
 
63
- # Clears the thread's token object. If called with 'true', it also
64
- # clears the token data from the cache.
65
- def self.clear_client_token!(clear_from_cache = false)
66
- cache.delete CLIENT_TOKEN_CACHE_KEY if clear_from_cache
67
- @client_token = nil
68
- true
51
+ def client_token
52
+ with_mutex { @client_token }
69
53
  end
70
54
 
71
55
  # Make a request to the API:
@@ -73,17 +57,15 @@ module NContent
73
57
  # @param [Symbol] verb the HTTP request method
74
58
  # @param [String] path the HTTP URL path of the request
75
59
  # @param [Hash] opts the options to make the request with
76
- def self.request(verb, path=nil, opts = {}, &block)
60
+ def request(verb, path=nil, opts = {}, &block)
77
61
 
78
- cleared_cached_token_data = false
62
+ retrying = false
79
63
 
80
64
  begin
81
65
 
82
- # If we beforehand know that the current token expired then clear the
83
- # token object from the current thread. We'll not clear it from the
84
- # cache store here, as maybe another thread has already updated the
85
- # cached token data:
86
- clear_client_token! if client_token.expired?
66
+ # If we beforehand know that the current token expired then the client
67
+ # token should be re-generated.
68
+ reset_client_token! if client_token.expired?
87
69
 
88
70
  client_token.request(verb, path, opts) do |req|
89
71
  req.options.timeout = config.api_call_timeout
@@ -93,37 +75,64 @@ module NContent
93
75
 
94
76
  rescue OAuth2::Error => error
95
77
 
96
- if error.response.status == 401 && !cleared_cached_token_data
97
- # Here the cached token data is stale, so we'll force the cached
98
- # token data to be cleared:
99
- cleared_cached_token_data = clear_client_token!(true)
78
+ if error.response.status == 401 && !retrying
79
+ reset_client_token!
80
+ retrying = true
81
+ logger.info "Retrying response #{verb.upcase} #{path} with a fresh nContent token."
100
82
  retry
101
83
  else
102
- ::NaranyaEcm::Rest::RestError.raise_by_failed_response(error.response)
84
+ NaranyaEcm::Rest::RestError.raise_by_failed_response(error.response)
103
85
  end
104
86
  end
105
87
  end
106
88
 
107
- def self.get(path=nil, opts = {}, &block)
89
+ def get(path=nil, opts = {}, &block)
108
90
  request(:get, path, opts, &block)
109
91
  end
110
92
 
111
- def self.post(path=nil, opts = {}, &block)
93
+ def post(path=nil, opts = {}, &block)
112
94
  request(:post, path, opts, &block)
113
95
  end
114
96
 
115
- def self.put(path=nil, opts = {}, &block)
97
+ def put(path=nil, opts = {}, &block)
116
98
  request(:put, path, opts, &block)
117
99
  end
118
100
 
119
- def self.patch(path=nil, opts = {}, &block)
101
+ def patch(path=nil, opts = {}, &block)
120
102
  request(:patch, path, opts, &block)
121
103
  end
122
104
 
123
- def self.delete(path=nil, opts = {}, &block)
105
+ def delete(path=nil, opts = {}, &block)
124
106
  request(:delete, path, opts, &block)
125
107
  end
126
108
 
109
+ class << self
110
+ delegate :client_token, :reset_client_token!, :request, :get, :post,
111
+ :put, :patch, :delete, to: :instance
112
+ end
113
+
114
+ private
115
+
116
+ def get_token
117
+ cached = cache.read CLIENT_TOKEN_CACHE_KEY
118
+
119
+ returned_token = if cached.present?
120
+ logger.debug "Generating client token from cached data: #{cached.inspect}"
121
+ OAuth2::AccessToken.from_hash @client, cached
122
+ else
123
+ logger.info "Requesting new client token from nContent server"
124
+ new_token = @client.client_credentials.get_token
125
+ cache.write CLIENT_TOKEN_CACHE_KEY, new_token.to_hash.with_indifferent_access
126
+ logger.debug "Data #{new_token.token.inspect} written to cache key #{CLIENT_TOKEN_CACHE_KEY}."
127
+ new_token
128
+ end
129
+ returned_token
130
+ end
131
+
132
+ def with_mutex
133
+ @mutex.synchronize { yield }
134
+ end
135
+
127
136
  end
128
137
 
129
138
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: naranya_ecm-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.43
4
+ version: 0.0.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Quintanilla
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-05-13 00:00:00.000000000 Z
11
+ date: 2015-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -233,6 +233,7 @@ files:
233
233
  - dev/init.rb
234
234
  - dev/load_cvm.rb
235
235
  - dev/search.rb
236
+ - dev/thread-safety-tests.rb
236
237
  - doc/media_processing.md
237
238
  - lib/aasm/persistence/rest_persistence.rb
238
239
  - lib/naranya_ecm-sdk.rb