-
Notifications
You must be signed in to change notification settings - Fork 549
/
distributed_counters.rb
101 lines (78 loc) · 3.12 KB
/
distributed_counters.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Copyright 2020 Google, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def create_counter project_id:, num_shards:, collection_path: "shards"
# [START firestore_solution_sharded_counter_create]
# project_id = "Your Google Cloud Project ID"
# num_shards = "Number of shards for distributed counter"
# collection_path = "shards"
require "google/cloud/firestore"
firestore = Google::Cloud::Firestore.new project_id: project_id
shards_ref = firestore.col collection_path
# Initialize each shard with count=0
num_shards.times do |i|
shards_ref.doc(i).set({ count: 0 })
end
puts "Distributed counter shards collection created."
# [END firestore_solution_sharded_counter_create]
end
def increment_counter project_id:, num_shards:, collection_path: "shards"
# [START firestore_solution_sharded_counter_increment]
# project_id = "Your Google Cloud Project ID"
# num_shards = "Number of shards for distributed counter"
# collection_path = "shards"
require "google/cloud/firestore"
firestore = Google::Cloud::Firestore.new project_id: project_id
# Select a shard of the counter at random
shard_id = rand 0...num_shards
shard_ref = firestore.doc "#{collection_path}/#{shard_id}"
# increment counter
shard_ref.update({ count: firestore.field_increment(1) })
puts "Counter incremented."
# [END firestore_solution_sharded_counter_increment]
end
def get_count project_id:, collection_path: "shards"
# [START firestore_solution_sharded_counter_get]
# project_id = "Your Google Cloud Project ID"
# collection_path = "shards"
require "google/cloud/firestore"
firestore = Google::Cloud::Firestore.new project_id: project_id
shards_ref = firestore.col_group collection_path
count = 0
shards_ref.get do |doc_ref|
count += doc_ref[:count]
end
puts "Count value is #{count}."
# [END firestore_solution_sharded_counter_get]
end
if $PROGRAM_NAME == __FILE__
project = ENV["FIRESTORE_PROJECT"]
case ARGV.shift
when "create_counter"
create_counter project_id: project, num_shards: ARGV.shift.to_i
when "increment_counter"
increment_counter project_id: project, num_shards: ARGV.shift.to_i
when "get_count"
get_count project_id: project
else
puts <<~USAGE
Usage: bundle exec ruby distributed_counters.rb [command] [arguments]
Commands:
create_counter <num_of_shards> Create distributed counter.
increment_counter <num_of_shards> Increment distributed counter.
get_count Get value of distributed counter.
Environment variables:
FIRESTORE_PROJECT must be set to your Google Cloud project ID
USAGE
end
end