spree_cm_commissioner 2.8.4.pre.pre4 → 2.8.4.pre.pre5

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
  SHA256:
3
- metadata.gz: 20f0a180f0ca53b77ce1c80dd3dc41e0d3049321aa02567ae35f23421828020c
4
- data.tar.gz: 52f68c03ee83f7b0863ebcda54c301be0f13f1584f026a6f46d574933e0f368e
3
+ metadata.gz: 65dbac61388e0427398c0ae91a6fbb9a8a17c22edf317b421c7070a3ee07980c
4
+ data.tar.gz: 2fb8bcf23633f432e5f3af10d77fc04cc4fa0899385282d18a6d99e672cb02f3
5
5
  SHA512:
6
- metadata.gz: 64e7b779a99ea18dfc44ecd1953f4e7878087754c55fe13fe741304ca4566b027e301638d2954ebdd19d1dc0e014b5119bb2ca7e73e0a36be05570db66c2eae0
7
- data.tar.gz: bf170f7c4fdba381ff89bd02393df9b5e8baad1d765d5542804beca8fef87f03088ac0a6903fd62e1017eba367d8653d1f44ad89b7396c91ed9fb1bc5f6c2f68
6
+ metadata.gz: aef422f9c1e17f2f92f93164cfbc979feb7d636fb7468847549e805ea79280544a4935b806aa5b28d6c99f1b15beb68803ba86c7dc0e22397e90e8a93c6baf31
7
+ data.tar.gz: 4ccdf815706a21cdd40fcfc02861fabf34c5792281a7101a306e92bc2b37665969a9aac7acbe02dfbcc535f020ec34b94e39f78e48679ce98b0ccf33ebd86f88
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (2.8.4.pre.pre4)
37
+ spree_cm_commissioner (2.8.4.pre.pre5)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -1,102 +1,13 @@
1
- require 'google/cloud/firestore'
2
-
3
1
  module SpreeCmCommissioner
4
2
  module WaitingRoom
5
3
  class StampQueuePositionsJob < ApplicationJob
6
4
  queue_as :waiting_room
7
5
 
8
- STAMP_LIMIT = (ENV['WAITING_ROOM_POSITION_STAMP_LIMIT'] || 1000).to_i
9
-
10
- # Firestore bounds a batch update by payload size (10 MiB); this batch size leaves 500/commit far under that.
11
- FIRESTORE_BATCH_SIZE = (ENV['WAITING_ROOM_FIRESTORE_BATCH_SIZE'] || 500).to_i
12
-
13
6
  def perform
14
- paths = stamp_paths
15
- avg_queue_to_enter = lobby_data[:avg_queue_to_enter_seconds].to_i
16
- total = paths.sum { |p| waiting_count(p) }
17
- return if total.zero?
18
-
19
- stamped_at = Time.zone.now
20
- global = 0
21
-
22
- paths.each do |path|
23
- remaining = STAMP_LIMIT - global
24
- break if remaining <= 0
25
-
26
- docs = waiting_query(path).order('queued_at').limit(remaining).get.to_a
27
-
28
- # Stamp the docs in chunks: each_slice splits them into groups of at most
29
- # FIRESTORE_BATCH_SIZE, and each group is written in one firestore.batch commit
30
- # (so e.g. 1000 docs = 2 commits, not 1000 round-trips).
31
- docs.each_slice(FIRESTORE_BATCH_SIZE) do |slice|
32
- firestore.batch do |b|
33
- slice.each do |doc|
34
- global += 1
35
-
36
- # The app shows a progress bar via (queue_total - position + 1) / queue_total.
37
- # `position` only ever counts down toward 1, so we keep `queue_total` from ever
38
- # going down either (max of its old value and the current position) — it becomes
39
- # the guest's starting depth. That keeps the bar moving only forward, reaching
40
- # 100% at position 1, instead of jumping as the live waiting count shrinks.
41
- #
42
- # Example — a guest who started 8th, with the line draining from 8 to 4 people:
43
- # live total: position 6 / total 8 = 38%, then position 4 / total 4 = 25% (drops!) ❌
44
- # this fix: position 6 / total 8 = 38%, then position 4 / total 8 = 63% (climbs) ✅
45
- # ...continuing to position 1 / total 8 = 100% at the front.
46
- data = {
47
- position: global,
48
- queue_total: [doc.data[:queue_total].to_i, global].max,
49
- estimated_wait_seconds: avg_queue_to_enter,
50
- status_updated_at: stamped_at
51
- }
52
-
53
- data[:position_set_at] = stamped_at unless doc.data[:position_set_at]
54
- b.update(doc.ref, data)
55
- end
56
- end
57
- end
58
- end
59
- end
60
-
61
- private
62
-
63
- def stamp_paths
64
- [previous_records_path, records_path]
65
- end
66
-
67
- def records_path
68
- default_records_path(Time.zone.now.strftime('%Y-%m-%d'))
69
- end
70
-
71
- def previous_records_path
72
- default_records_path(1.day.ago.strftime('%Y-%m-%d'))
73
- end
74
-
75
- def default_records_path(date)
76
- "waiting_guests/#{date}/records"
77
- end
78
-
79
- def waiting_count(path)
80
- waiting_query(path).aggregate_query.add_count.get.first.get.to_i
81
- end
82
-
83
- def waiting_query(path)
84
- firestore.col(path).where('allow_to_enter_room_at', '==', nil)
85
- end
86
-
87
- def lobby_data
88
- @lobby_data ||= firestore.col('waiting_rooms').doc('lobby').get.data || {}
89
- end
90
-
91
- def firestore
92
- @firestore ||= Google::Cloud::Firestore.new(
93
- project_id: service_account[:project_id],
94
- credentials: service_account
95
- )
96
- end
7
+ return if ENV['WAITING_ROOM_DISABLED'] == 'yes'
97
8
 
98
- def service_account
99
- @service_account ||= Rails.application.credentials.cloud_firestore_service_account
9
+ # call! so a stamping failure raises (Sidekiq retries/alerts) instead of being silently swallowed.
10
+ SpreeCmCommissioner::WaitingRoom::StampQueuePositions.call!
100
11
  end
101
12
  end
102
13
  end
@@ -0,0 +1,114 @@
1
+ require 'google/cloud/firestore'
2
+
3
+ module SpreeCmCommissioner
4
+ module WaitingRoom
5
+ # Stamps queue positions onto waiting-guest Firestore docs so the app can render each guest's
6
+ # place in line and a forward-only progress bar. Walks the day partitions oldest-first, assigning
7
+ # a continuous global position (1, 2, 3, ...) capped at STAMP_LIMIT, and commits in Firestore
8
+ # batches to stay under the 10 MiB/commit payload bound.
9
+ class StampQueuePositions
10
+ prepend ::Spree::ServiceModule::Base
11
+ extend SpreeCmCommissioner::ServiceModuleThrowable
12
+
13
+ STAMP_LIMIT = (ENV['WAITING_ROOM_POSITION_STAMP_LIMIT'] || 1000).to_i
14
+
15
+ # Firestore bounds a batch update by payload size (10 MiB); this batch size leaves 500/commit far under that.
16
+ FIRESTORE_BATCH_SIZE = (ENV['WAITING_ROOM_FIRESTORE_BATCH_SIZE'] || 500).to_i
17
+
18
+ def call
19
+ stamp_positions
20
+ success(stamped: @stamped.to_i)
21
+ rescue StandardError => e
22
+ failure(nil, e.message)
23
+ end
24
+
25
+ private
26
+
27
+ def stamp_positions
28
+ paths = stamp_paths
29
+ avg_queue_to_enter = lobby_data[:avg_queue_to_enter_seconds].to_i
30
+ total = paths.sum { |p| waiting_count(p) }
31
+ return if total.zero?
32
+
33
+ stamped_at = Time.zone.now
34
+ @stamped = 0
35
+
36
+ paths.each do |path|
37
+ remaining = STAMP_LIMIT - @stamped
38
+ break if remaining <= 0
39
+
40
+ docs = waiting_query(path).order('queued_at').limit(remaining).get.to_a
41
+
42
+ # Stamp the docs in chunks: each_slice splits them into groups of at most
43
+ # FIRESTORE_BATCH_SIZE, and each group is written in one firestore.batch commit
44
+ # (so e.g. 1000 docs = 2 commits, not 1000 round-trips).
45
+ docs.each_slice(FIRESTORE_BATCH_SIZE) do |slice|
46
+ firestore.batch do |b|
47
+ slice.each { |doc| stamp_doc(b, doc, avg_queue_to_enter, stamped_at) }
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def stamp_doc(batch, doc, avg_queue_to_enter, stamped_at)
54
+ @stamped += 1
55
+
56
+ # The app shows a progress bar via (queue_total - position + 1) / queue_total.
57
+ # `position` only ever counts down toward 1, so we keep `queue_total` from ever
58
+ # going down either (max of its old value and the current position) — it becomes
59
+ # the guest's starting depth. That keeps the bar moving only forward, reaching
60
+ # 100% at position 1, instead of jumping as the live waiting count shrinks.
61
+ #
62
+ # Example — a guest who started 8th, with the line draining from 8 to 4 people:
63
+ # live total: position 6 / total 8 = 38%, then position 4 / total 4 = 25% (drops!) ❌
64
+ # this fix: position 6 / total 8 = 38%, then position 4 / total 8 = 63% (climbs) ✅
65
+ # ...continuing to position 1 / total 8 = 100% at the front.
66
+ data = {
67
+ position: @stamped,
68
+ queue_total: [doc.data[:queue_total].to_i, @stamped].max,
69
+ estimated_wait_seconds: avg_queue_to_enter,
70
+ status_updated_at: stamped_at
71
+ }
72
+
73
+ data[:position_set_at] = stamped_at unless doc.data[:position_set_at]
74
+ batch.update(doc.ref, data)
75
+ end
76
+
77
+ def stamp_paths
78
+ [previous_records_path, records_path]
79
+ end
80
+
81
+ def records_path
82
+ default_records_path(Time.zone.now.strftime('%Y-%m-%d'))
83
+ end
84
+
85
+ def previous_records_path
86
+ default_records_path(1.day.ago.strftime('%Y-%m-%d'))
87
+ end
88
+
89
+ def default_records_path(date)
90
+ "waiting_guests/#{date}/records"
91
+ end
92
+
93
+ def waiting_count(path)
94
+ waiting_query(path).aggregate_query.add_count.get.first.get.to_i
95
+ end
96
+
97
+ def waiting_query(path)
98
+ firestore.col(path).where('allow_to_enter_room_at', '==', nil)
99
+ end
100
+
101
+ def lobby_data
102
+ @lobby_data ||= firestore.col('waiting_rooms').doc('lobby').get.data || {}
103
+ end
104
+
105
+ def firestore
106
+ @firestore ||= Google::Cloud::Firestore.new(project_id: service_account[:project_id], credentials: service_account)
107
+ end
108
+
109
+ def service_account
110
+ @service_account ||= Rails.application.credentials.cloud_firestore_service_account
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '2.8.4-pre4'.freeze
2
+ VERSION = '2.8.4-pre5'.freeze
3
3
 
4
4
  module_function
5
5
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_cm_commissioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.4.pre.pre4
4
+ version: 2.8.4.pre.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
@@ -2264,6 +2264,7 @@ files:
2264
2264
  - app/services/spree_cm_commissioner/vendor_route_metrics/decrease_trip_count.rb
2265
2265
  - app/services/spree_cm_commissioner/vendor_route_metrics/increase_trip_count.rb
2266
2266
  - app/services/spree_cm_commissioner/waiting_room/publish_lobby_path.rb
2267
+ - app/services/spree_cm_commissioner/waiting_room/stamp_queue_positions.rb
2267
2268
  - app/services/spree_cm_commissioner/waiting_room_lobby_metadata_fetcher.rb
2268
2269
  - app/services/spree_cm_commissioner/waiting_room_system_metadata_fetcher.rb
2269
2270
  - app/services/spree_cm_commissioner/waiting_room_system_metadata_setter.rb