lifen 1.5.1 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c313933ddbf8bc22bfb69240a8447044cb03fd4
4
- data.tar.gz: 3ec79fe55b174797095f8bda5a01a8df52e5272f
3
+ metadata.gz: 6f1aef95bf44e742592d04b253e4b19f6bdb9eb7
4
+ data.tar.gz: 9ff4e2c43626c1bc379e31de7b65dd97e125aaeb
5
5
  SHA512:
6
- metadata.gz: b0f42ad92dcdbfba42102b977b2b9437c5c8ba29da1549b75b513e0322d13f56586c2884a68d918d25772b95dc3f05c27cc8af6d4f88f9748d3a4357357dd39c
7
- data.tar.gz: 73fadebb9cb5d67dff05d0587f49f3c3d44d04fac5f7410d40919760aedf67fa0c605d15e0a42da34ee33987b73df347d615f001a99be58acefbbc889e0a131a
6
+ metadata.gz: b3cc34906d28323e88bbf86c336cd278a04ee9565e01631c08fc038f68c57066b4427ba41a6aba0f1c35ca1a462a2f1d47fe1ff613eed02cfdf4760290f2c106
7
+ data.tar.gz: 694710ae26fc1cc8f59a974c883da5cee4a80e6a0d2cb892f665271a657d187a7592d2a3654ee4acde76c237d70722673bbafcc0e6e54431757bf65e18b25b02
@@ -1,7 +1,12 @@
1
+ 1.5.2
2
+ -----
3
+
4
+ - Threadsafe strategy for the user creation to include the persistence strategy
5
+
1
6
  1.5.1
2
7
  -----
3
8
 
4
- - Threadsafe strategy needed to included the persistence strategy
9
+ - Threadsafe strategy for the token refresh to include the persistence strategy
5
10
 
6
11
  1.5.0
7
12
  -----
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lifen (1.5.1)
4
+ lifen (1.5.2)
5
5
  faraday (>= 0.9)
6
6
  inflecto
7
7
  virtus (>= 1.0)
@@ -71,4 +71,4 @@ DEPENDENCIES
71
71
  webmock (~> 1.24)
72
72
 
73
73
  BUNDLED WITH
74
- 1.13.6
74
+ 1.13.7
data/README.md CHANGED
@@ -54,6 +54,30 @@ other_user.save
54
54
  other_user.reload
55
55
  ```
56
56
 
57
+ ### Creating a user in a threadsafe way
58
+
59
+ Assuming the lifen `uuid` is stored on the `User` model as `lifen_uuid`, you can simply change the `create` method to became threadsafe:
60
+
61
+ ```ruby
62
+ lifen_user.create(
63
+ persisted_lifen_uuid: ->(internal_user) {
64
+ user.reload
65
+
66
+ current_uuid = user.lifen_uuid
67
+
68
+ if current_uuid.blank?
69
+ nil
70
+ else
71
+ current_uuid
72
+ end
73
+ },
74
+ save_to_db: ->(lifen_user) {
75
+ user.lifen_uuid = lifen_user.uuid
76
+ user.save!
77
+ }
78
+ )
79
+ ```
80
+
57
81
  ### Managing users' settings
58
82
 
59
83
  ```ruby
@@ -1,7 +1,7 @@
1
1
  module Lifen
2
2
  class Token
3
3
 
4
- @@lock = Mutex.new
4
+ @@refresh_lock = Mutex.new
5
5
 
6
6
  include Virtus.model(finalize: false)
7
7
 
@@ -45,7 +45,7 @@ module Lifen
45
45
  end
46
46
 
47
47
  def refresh_once_if_needed
48
- @@lock.synchronize do
48
+ @@refresh_lock.synchronize do
49
49
 
50
50
  load_from_db.call(self) if load_from_db.is_a? Proc
51
51
 
@@ -12,16 +12,35 @@ module Lifen
12
12
  attribute :first_name, String
13
13
  attribute :profile_picture_url, String
14
14
 
15
+ @@create_lock = Mutex.new
16
+
15
17
  def flows
16
18
  Lifen::Flows.new(user: self).all
17
19
  end
18
20
 
19
- def create
21
+ def create(persisted_lifen_uuid: ->(user) {}, save_to_db: ->(user) {})
22
+
20
23
  params = {emailAddress: email, lastName: last_name, firstName: first_name, profilePicUrl: profile_picture_url}
21
24
 
22
- json = application_client.post("authentication/api/register/third_party", params)
25
+ @@create_lock.synchronize do
26
+
27
+ exisiting_uuid = persisted_lifen_uuid.call(self)
28
+
29
+ if exisiting_uuid.nil?
30
+
31
+ json = application_client.post("authentication/api/register/third_party", params)
32
+
33
+ self.uuid = json["accountUuid"]
34
+
35
+ else
36
+
37
+ self.uuid = exisiting_uuid
38
+
39
+ end
40
+
41
+ save_to_db.call(self)
42
+ end
23
43
 
24
- self.uuid = json["accountUuid"]
25
44
  end
26
45
 
27
46
  def self.find(uuid)
@@ -1,3 +1,3 @@
1
1
  module Lifen
2
- VERSION = "1.5.1"
2
+ VERSION = "1.5.2"
3
3
  end
@@ -94,7 +94,7 @@ describe Lifen::Token do
94
94
  token.expires_at = persisted_user.token_expires_at
95
95
  },
96
96
  save_to_db: ->(token) {
97
- # Loading data from DB
97
+ # Saving data to DB
98
98
 
99
99
  persisted_user.token_value = token.value
100
100
  persisted_user.token_expires_at = token.expires_at
@@ -64,6 +64,65 @@ describe Lifen::User do
64
64
 
65
65
  expect(user.uuid).to_not be_nil
66
66
  end
67
+
68
+ describe 'thread safe' do
69
+
70
+ class PersistedUser < Struct.new(:lifen_uuid) ; end
71
+
72
+ let(:storage) { double("Storage") }
73
+
74
+ let(:marc) { Lifen::User.new(email: "existing-user@domain.tld", first_name: "Existing", last_name: "User") }
75
+ let(:antoine) { Lifen::User.new(email: "existing-user@domain.tld", first_name: "Existing", last_name: "Marc") }
76
+
77
+ before do
78
+ allow(storage).to receive(:find_by) do
79
+ PersistedUser.new(nil)
80
+ end
81
+ end
82
+
83
+ it 'queues refresh calls' do
84
+
85
+ threads = []
86
+
87
+ threads << Thread.new do
88
+ VCR.use_cassette "users/create/valid_attributes" do
89
+ marc.create(
90
+ persisted_lifen_uuid: ->(user) {
91
+ # Loading data from DB
92
+ storage.find_by(email: user.email).lifen_uuid
93
+ },
94
+ save_to_db: ->(user) {
95
+ # saving data to DB
96
+
97
+ allow(storage).to receive(:find_by) do
98
+ PersistedUser.new(user.uuid)
99
+ end
100
+ }
101
+ )
102
+ end
103
+ end
104
+
105
+ sleep 0.1 # Making sure the mocked call is received first
106
+
107
+ threads << Thread.new do
108
+
109
+ # No cassette, should raise an issue if HTTP call is needed
110
+ antoine.create(
111
+ persisted_lifen_uuid: ->(user) {
112
+ # Loading data from DB
113
+
114
+ storage.find_by(email: user.email).lifen_uuid
115
+ }
116
+ )
117
+ end
118
+
119
+ threads.map { |t| t.join } # waiting for all threads to finish
120
+ end
121
+
122
+ end
123
+
124
+
125
+
67
126
  end
68
127
 
69
128
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lifen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Etienne Depaulis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-12 00:00:00.000000000 Z
11
+ date: 2017-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  version: '0'
223
223
  requirements: []
224
224
  rubyforge_project:
225
- rubygems_version: 2.5.2
225
+ rubygems_version: 2.6.8
226
226
  signing_key:
227
227
  specification_version: 4
228
228
  summary: Lifen JSON API ruby client