lifen 1.5.1 → 1.5.2

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: 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