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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 65dbac61388e0427398c0ae91a6fbb9a8a17c22edf317b421c7070a3ee07980c
|
|
4
|
+
data.tar.gz: 2fb8bcf23633f432e5f3af10d77fc04cc4fa0899385282d18a6d99e672cb02f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aef422f9c1e17f2f92f93164cfbc979feb7d636fb7468847549e805ea79280544a4935b806aa5b28d6c99f1b15beb68803ba86c7dc0e22397e90e8a93c6baf31
|
|
7
|
+
data.tar.gz: 4ccdf815706a21cdd40fcfc02861fabf34c5792281a7101a306e92bc2b37665969a9aac7acbe02dfbcc535f020ec34b94e39f78e48679ce98b0ccf33ebd86f88
|
data/Gemfile.lock
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
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.
|
|
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
|