analytics-ruby 2.2.3.pre → 2.2.4.pre
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 +5 -5
- data/History.md +16 -0
- data/Makefile +17 -8
- data/README.md +2 -2
- data/RELEASING.md +2 -3
- data/Rakefile +17 -1
- data/analytics-ruby.gemspec +10 -2
- data/codecov.yml +2 -0
- data/lib/analytics-ruby.rb +1 -0
- data/lib/segment/analytics.rb +9 -2
- data/lib/segment/analytics/backoff_policy.rb +49 -0
- data/lib/segment/analytics/client.rb +148 -99
- data/lib/segment/analytics/defaults.rb +20 -4
- data/lib/segment/analytics/logging.rb +2 -4
- data/lib/segment/analytics/message.rb +26 -0
- data/lib/segment/analytics/message_batch.rb +58 -0
- data/lib/segment/analytics/request.rb +84 -32
- data/lib/segment/analytics/response.rb +0 -1
- data/lib/segment/analytics/utils.rb +19 -16
- data/lib/segment/analytics/version.rb +1 -1
- data/lib/segment/analytics/worker.rb +11 -10
- data/spec/helpers/runscope_client.rb +38 -0
- data/spec/segment/analytics/backoff_policy_spec.rb +92 -0
- data/spec/segment/analytics/client_spec.rb +61 -44
- data/spec/segment/analytics/e2e_spec.rb +48 -0
- data/spec/segment/analytics/message_batch_spec.rb +49 -0
- data/spec/segment/analytics/message_spec.rb +35 -0
- data/spec/segment/analytics/request_spec.rb +87 -34
- data/spec/segment/analytics/worker_spec.rb +24 -16
- data/spec/spec_helper.rb +32 -6
- metadata +73 -17
- data/Gemfile.lock +0 -43
- data/analytics-ruby-2.0.13.gem +0 -0
- data/analytics-ruby-2.1.0.gem +0 -0
- data/analytics-ruby-2.2.2.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 276383d9b3932f6d39493e74cf48ec05fb6805050c4031acd77a245e9b6e6d4e
|
4
|
+
data.tar.gz: ebe9076f70b26805478f40a3c45bbf5c13bdd8de6083081651cbc1a3476f6e4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d5ba302e4d25b5155a8d273d8e9d406bce39e5bb906f205afd58c86fcd816f90512fb7117b6a19c98a5b7bde3d1b8c8e8158465a3c04154e6bfee9ca406602f
|
7
|
+
data.tar.gz: 7b935c07754a56217f8735161bab41920bcd4b8bea94359c8a0d5cd04e0b2bb2d63ff3aff478eb72f6978922b63c00d22027f24949d0badef6e7b659b573f5c6
|
data/History.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
2.2.4.pre / 2018-02-04
|
2
|
+
==================
|
3
|
+
|
4
|
+
* [Fix](https://github.com/segmentio/analytics-ruby/pull/147): Prevent 'batch
|
5
|
+
size exceeded' errors by automatically batching
|
6
|
+
items according to size
|
7
|
+
* [Performance](https://github.com/segmentio/analytics-ruby/pull/149): Reuse
|
8
|
+
TCP connections
|
9
|
+
* [Improvement](https://github.com/segmentio/analytics-ruby/pull/145): Emit logs
|
10
|
+
when in-memory queue is full
|
11
|
+
* [Improvement](https://github.com/segmentio/analytics-ruby/pull/143): Emit logs
|
12
|
+
when messages exceed maximum allowed size
|
13
|
+
* [Improvement](https://github.com/segmentio/analytics-ruby/pull/134): Add
|
14
|
+
exponential backoff to retries
|
15
|
+
* [Improvement](https://github.com/segmentio/analytics-ruby/pull/132): Handle
|
16
|
+
HTTP status code failure appropriately
|
1
17
|
|
2
18
|
2.2.3.pre / 2017-09-14
|
3
19
|
==================
|
data/Makefile
CHANGED
@@ -1,8 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
|
2
|
+
# Install any tools required to build this library, e.g. Ruby, Bundler etc.
|
3
|
+
bootstrap:
|
4
|
+
brew install ruby
|
5
|
+
gem install bundler
|
6
|
+
|
7
|
+
# Install any library dependencies.
|
8
|
+
dependencies:
|
9
|
+
bundle install --verbose
|
10
|
+
|
11
|
+
# Run all tests and checks (including linters).
|
12
|
+
check:
|
13
|
+
bundle exec rake
|
14
|
+
|
15
|
+
# Compile the code and produce any binaries where applicable.
|
16
|
+
build:
|
17
|
+
gem build ./analytics-ruby.gemspec
|
data/README.md
CHANGED
@@ -9,11 +9,11 @@ analytics-ruby is a ruby client for [Segment](https://segment.com)
|
|
9
9
|
|
10
10
|
Into Gemfile from rubygems.org:
|
11
11
|
```ruby
|
12
|
-
gem 'analytics-ruby'
|
12
|
+
gem 'analytics-ruby'
|
13
13
|
```
|
14
14
|
|
15
15
|
Into environment gems from rubygems.org:
|
16
|
-
```
|
16
|
+
```
|
17
17
|
gem install 'analytics-ruby'
|
18
18
|
```
|
19
19
|
|
data/RELEASING.md
CHANGED
@@ -5,6 +5,5 @@ Releasing
|
|
5
5
|
2. Bump version in [`version.rb`](https://github.com/segmentio/analytics-ruby/blob/master/lib/segment/analytics/version.rb).
|
6
6
|
3. Update [`History.md`](https://github.com/segmentio/analytics-ruby/blob/master/History.md).
|
7
7
|
4. Commit and tag `git commit -am "Release {version}" && git tag -a {version} -m "Version {version}"`.
|
8
|
-
5.
|
9
|
-
|
10
|
-
7. Upload to Github with `git push -u origin master && git push --tags`.
|
8
|
+
5. Upload to Github with `git push -u origin master && git push --tags`.
|
9
|
+
The tagged commit will be pushed to RubyGems via Travis.
|
data/Rakefile
CHANGED
@@ -1,7 +1,23 @@
|
|
1
1
|
require 'rspec/core/rake_task'
|
2
2
|
|
3
|
+
default_tasks = []
|
4
|
+
|
3
5
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
4
6
|
spec.pattern = 'spec/**/*_spec.rb'
|
7
|
+
spec.rspec_opts = "--tag ~e2e" if ENV["RUN_E2E_TESTS"] != "true"
|
8
|
+
end
|
9
|
+
|
10
|
+
default_tasks << :spec
|
11
|
+
|
12
|
+
# Rubocop doesn't support < 2.1
|
13
|
+
if RUBY_VERSION >= "2.1"
|
14
|
+
require 'rubocop/rake_task'
|
15
|
+
|
16
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
17
|
+
task.patterns = ['lib/**/*.rb','spec/**/*.rb',]
|
18
|
+
end
|
19
|
+
|
20
|
+
default_tasks << :rubocop
|
5
21
|
end
|
6
22
|
|
7
|
-
task :default =>
|
23
|
+
task :default => default_tasks
|
data/analytics-ruby.gemspec
CHANGED
@@ -19,7 +19,15 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.add_dependency 'commander', '~> 4.4'
|
20
20
|
|
21
21
|
spec.add_development_dependency 'rake', '~> 10.3'
|
22
|
-
spec.add_development_dependency 'rspec', '~>
|
22
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
23
23
|
spec.add_development_dependency 'tzinfo', '1.2.1'
|
24
|
-
spec.add_development_dependency 'activesupport', '
|
24
|
+
spec.add_development_dependency 'activesupport', '~> 4.1.11'
|
25
|
+
spec.add_development_dependency 'faraday', '~> 0.13'
|
26
|
+
spec.add_development_dependency 'pmap', '~> 1.1'
|
27
|
+
|
28
|
+
if RUBY_VERSION >= "2.1"
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 0.51.0'
|
30
|
+
end
|
31
|
+
|
32
|
+
spec.add_development_dependency 'codecov', '~> 0.1.4'
|
25
33
|
end
|
data/codecov.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'segment'
|
data/lib/segment/analytics.rb
CHANGED
@@ -9,12 +9,19 @@ require 'segment/analytics/logging'
|
|
9
9
|
|
10
10
|
module Segment
|
11
11
|
class Analytics
|
12
|
-
|
12
|
+
# Initializes a new instance of {Segment::Analytics::Client}, to which all
|
13
|
+
# method calls are proxied.
|
14
|
+
#
|
15
|
+
# @param options includes options that are passed down to
|
16
|
+
# {Segment::Analytics::Client#initialize}
|
17
|
+
# @option options [Boolean] :stub (false) If true, requests don't hit the
|
18
|
+
# server and are stubbed to be successful.
|
19
|
+
def initialize(options = {})
|
13
20
|
Request.stub = options[:stub] if options.has_key?(:stub)
|
14
21
|
@client = Segment::Analytics::Client.new options
|
15
22
|
end
|
16
23
|
|
17
|
-
def method_missing
|
24
|
+
def method_missing(message, *args, &block)
|
18
25
|
if @client.respond_to? message
|
19
26
|
@client.send message, *args, &block
|
20
27
|
else
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'segment/analytics/defaults'
|
2
|
+
|
3
|
+
module Segment
|
4
|
+
class Analytics
|
5
|
+
class BackoffPolicy
|
6
|
+
include Segment::Analytics::Defaults::BackoffPolicy
|
7
|
+
|
8
|
+
# @param [Hash] opts
|
9
|
+
# @option opts [Numeric] :min_timeout_ms The minimum backoff timeout
|
10
|
+
# @option opts [Numeric] :max_timeout_ms The maximum backoff timeout
|
11
|
+
# @option opts [Numeric] :multiplier The value to multiply the current
|
12
|
+
# interval with for each retry attempt
|
13
|
+
# @option opts [Numeric] :randomization_factor The randomization factor
|
14
|
+
# to use to create a range around the retry interval
|
15
|
+
def initialize(opts = {})
|
16
|
+
@min_timeout_ms = opts[:min_timeout_ms] || MIN_TIMEOUT_MS
|
17
|
+
@max_timeout_ms = opts[:max_timeout_ms] || MAX_TIMEOUT_MS
|
18
|
+
@multiplier = opts[:multiplier] || MULTIPLIER
|
19
|
+
@randomization_factor = opts[:randomization_factor] || RANDOMIZATION_FACTOR
|
20
|
+
|
21
|
+
@attempts = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Numeric] the next backoff interval, in milliseconds.
|
25
|
+
def next_interval
|
26
|
+
interval = @min_timeout_ms * (@multiplier**@attempts)
|
27
|
+
interval = add_jitter(interval, @randomization_factor)
|
28
|
+
|
29
|
+
@attempts += 1
|
30
|
+
|
31
|
+
[interval, @max_timeout_ms].min
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def add_jitter(base, randomization_factor)
|
37
|
+
random_number = rand
|
38
|
+
max_deviation = base * randomization_factor
|
39
|
+
deviation = random_number * max_deviation
|
40
|
+
|
41
|
+
if random_number < 0.5
|
42
|
+
base - deviation
|
43
|
+
else
|
44
|
+
base + deviation
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,39 +1,41 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'time'
|
3
|
+
|
4
|
+
require 'segment/analytics/defaults'
|
5
|
+
require 'segment/analytics/logging'
|
3
6
|
require 'segment/analytics/utils'
|
4
7
|
require 'segment/analytics/worker'
|
5
|
-
require 'segment/analytics/defaults'
|
6
8
|
|
7
9
|
module Segment
|
8
10
|
class Analytics
|
9
11
|
class Client
|
10
12
|
include Segment::Analytics::Utils
|
13
|
+
include Segment::Analytics::Logging
|
11
14
|
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
symbolize_keys! attrs
|
15
|
+
# @param [Hash] opts
|
16
|
+
# @option opts [String] :write_key Your project's write_key
|
17
|
+
# @option opts [FixNum] :max_queue_size Maximum number of calls to be
|
18
|
+
# remain queued.
|
19
|
+
# @option opts [Proc] :on_error Handles error calls from the API.
|
20
|
+
def initialize(opts = {})
|
21
|
+
symbolize_keys!(opts)
|
20
22
|
|
21
23
|
@queue = Queue.new
|
22
|
-
@write_key =
|
23
|
-
@max_queue_size =
|
24
|
-
@options =
|
24
|
+
@write_key = opts[:write_key]
|
25
|
+
@max_queue_size = opts[:max_queue_size] || Defaults::Queue::MAX_SIZE
|
26
|
+
@options = opts
|
25
27
|
@worker_mutex = Mutex.new
|
26
|
-
@worker = Worker.new
|
28
|
+
@worker = Worker.new(@queue, @write_key, @options)
|
27
29
|
|
28
30
|
check_write_key!
|
29
31
|
|
30
32
|
at_exit { @worker_thread && @worker_thread[:should_exit] = true }
|
31
33
|
end
|
32
34
|
|
33
|
-
#
|
34
|
-
# Use only for scripts which are not long-running, and will
|
35
|
-
# specifically exit
|
35
|
+
# Synchronously waits until the worker has flushed the queue.
|
36
36
|
#
|
37
|
+
# Use only for scripts which are not long-running, and will specifically
|
38
|
+
# exit
|
37
39
|
def flush
|
38
40
|
while !@queue.empty? || @worker.is_requesting?
|
39
41
|
ensure_worker_running
|
@@ -41,19 +43,26 @@ module Segment
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
#
|
46
|
+
# Tracks an event
|
45
47
|
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
|
48
|
+
# @see https://segment.com/docs/sources/server/ruby/#track
|
49
|
+
#
|
50
|
+
# @param [Hash] attrs
|
51
|
+
# @option attrs [String] :anonymous_id ID for a user when you don't know
|
52
|
+
# who they are yet. (optional but you must provide either an
|
53
|
+
# `anonymous_id` or `user_id`)
|
54
|
+
# @option attrs [Hash] :context ({})
|
55
|
+
# @option attrs [String] :event Event name
|
56
|
+
# @option attrs [Hash] :integrations What integrations this event
|
57
|
+
# goes to (optional)
|
58
|
+
# @option attrs [Hash] :options Options such as user traits (optional)
|
59
|
+
# @option attrs [Hash] :properties Event properties (optional)
|
60
|
+
# @option attrs [Time] :timestamp When the event occurred (optional)
|
61
|
+
# @option attrs [String] :user_id The ID for this user in your database
|
62
|
+
# (optional but you must provide either an `anonymous_id` or `user_id`)
|
63
|
+
# @option attrs [String] :message_id ID that uniquely
|
64
|
+
# identifies a message across the API. (optional)
|
65
|
+
def track(attrs)
|
57
66
|
symbolize_keys! attrs
|
58
67
|
check_user_id! attrs
|
59
68
|
|
@@ -66,10 +75,10 @@ module Segment
|
|
66
75
|
check_timestamp! timestamp
|
67
76
|
|
68
77
|
if event.nil? || event.empty?
|
69
|
-
|
78
|
+
raise ArgumentError, 'Must supply event as a non-empty string'
|
70
79
|
end
|
71
80
|
|
72
|
-
|
81
|
+
raise ArgumentError, 'Properties must be a Hash' unless properties.is_a? Hash
|
73
82
|
isoify_dates! properties
|
74
83
|
|
75
84
|
add_context context
|
@@ -88,18 +97,25 @@ module Segment
|
|
88
97
|
})
|
89
98
|
end
|
90
99
|
|
91
|
-
#
|
100
|
+
# Identifies a user
|
101
|
+
#
|
102
|
+
# @see https://segment.com/docs/sources/server/ruby/#identify
|
92
103
|
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
|
104
|
+
# @param [Hash] attrs
|
105
|
+
# @option attrs [String] :anonymous_id ID for a user when you don't know
|
106
|
+
# who they are yet. (optional but you must provide either an
|
107
|
+
# `anonymous_id` or `user_id`)
|
108
|
+
# @option attrs [Hash] :context ({})
|
109
|
+
# @option attrs [Hash] :integrations What integrations this event
|
110
|
+
# goes to (optional)
|
111
|
+
# @option attrs [Hash] :options Options such as user traits (optional)
|
112
|
+
# @option attrs [Time] :timestamp When the event occurred (optional)
|
113
|
+
# @option attrs [Hash] :traits User traits (optional)
|
114
|
+
# @option attrs [String] :user_id The ID for this user in your database
|
115
|
+
# (optional but you must provide either an `anonymous_id` or `user_id`)
|
116
|
+
# @option attrs [String] :message_id ID that uniquely identifies a
|
117
|
+
# message across the API. (optional)
|
118
|
+
def identify(attrs)
|
103
119
|
symbolize_keys! attrs
|
104
120
|
check_user_id! attrs
|
105
121
|
|
@@ -110,7 +126,7 @@ module Segment
|
|
110
126
|
|
111
127
|
check_timestamp! timestamp
|
112
128
|
|
113
|
-
|
129
|
+
raise ArgumentError, 'Must supply traits as a hash' unless traits.is_a? Hash
|
114
130
|
isoify_dates! traits
|
115
131
|
|
116
132
|
add_context context
|
@@ -128,16 +144,20 @@ module Segment
|
|
128
144
|
})
|
129
145
|
end
|
130
146
|
|
131
|
-
#
|
147
|
+
# Aliases a user from one id to another
|
132
148
|
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
149
|
+
# @see https://segment.com/docs/sources/server/ruby/#alias
|
150
|
+
#
|
151
|
+
# @param [Hash] attrs
|
152
|
+
# @option attrs [Hash] :context ({})
|
153
|
+
# @option attrs [Hash] :integrations What integrations this must be
|
154
|
+
# sent to (optional)
|
155
|
+
# @option attrs [Hash] :options Options such as user traits (optional)
|
156
|
+
# @option attrs [String] :previous_id The ID to alias from
|
157
|
+
# @option attrs [Time] :timestamp When the alias occurred (optional)
|
158
|
+
# @option attrs [String] :user_id The ID to alias to
|
159
|
+
# @option attrs [String] :message_id ID that uniquely identifies a
|
160
|
+
# message across the API. (optional)
|
141
161
|
def alias(attrs)
|
142
162
|
symbolize_keys! attrs
|
143
163
|
|
@@ -164,16 +184,24 @@ module Segment
|
|
164
184
|
})
|
165
185
|
end
|
166
186
|
|
167
|
-
#
|
187
|
+
# Associates a user identity with a group.
|
188
|
+
#
|
189
|
+
# @see https://segment.com/docs/sources/server/ruby/#group
|
168
190
|
#
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
191
|
+
# @param [Hash] attrs
|
192
|
+
# @option attrs [String] :anonymous_id ID for a user when you don't know
|
193
|
+
# who they are yet. (optional but you must provide either an
|
194
|
+
# `anonymous_id` or `user_id`)
|
195
|
+
# @option attrs [Hash] :context ({})
|
196
|
+
# @option attrs [String] :group_id The ID of the group
|
197
|
+
# @option attrs [Hash] :integrations What integrations this event
|
198
|
+
# goes to (optional)
|
199
|
+
# @option attrs [Hash] :options Options such as user traits (optional)
|
200
|
+
# @option attrs [Time] :timestamp When the event occurred (optional)
|
201
|
+
# @option attrs [String] :user_id The ID for the user that is part of
|
202
|
+
# the group
|
203
|
+
# @option attrs [String] :message_id ID that uniquely identifies a
|
204
|
+
# message across the API. (optional)
|
177
205
|
def group(attrs)
|
178
206
|
symbolize_keys! attrs
|
179
207
|
check_user_id! attrs
|
@@ -185,7 +213,7 @@ module Segment
|
|
185
213
|
context = attrs[:context] || {}
|
186
214
|
message_id = attrs[:message_id].to_s if attrs[:message_id]
|
187
215
|
|
188
|
-
|
216
|
+
raise ArgumentError, '.traits must be a hash' unless traits.is_a? Hash
|
189
217
|
isoify_dates! traits
|
190
218
|
|
191
219
|
check_presence! group_id, 'group_id'
|
@@ -205,19 +233,25 @@ module Segment
|
|
205
233
|
})
|
206
234
|
end
|
207
235
|
|
208
|
-
#
|
236
|
+
# Records a page view
|
209
237
|
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
238
|
+
# @see https://segment.com/docs/sources/server/ruby/#page
|
239
|
+
#
|
240
|
+
# @param [Hash] attrs
|
241
|
+
# @option attrs [String] :anonymous_id ID for a user when you don't know
|
242
|
+
# who they are yet. (optional but you must provide either an
|
243
|
+
# `anonymous_id` or `user_id`)
|
244
|
+
# @option attrs [String] :category The page category (optional)
|
245
|
+
# @option attrs [Hash] :context ({})
|
246
|
+
# @option attrs [Hash] :integrations What integrations this event
|
247
|
+
# goes to (optional)
|
248
|
+
# @option attrs [String] :name Name of the page
|
249
|
+
# @option attrs [Hash] :options Options such as user traits (optional)
|
250
|
+
# @option attrs [Hash] :properties Page properties (optional)
|
251
|
+
# @option attrs [Time] :timestamp When the pageview occurred (optional)
|
252
|
+
# @option attrs [String] :user_id The ID of the user viewing the page
|
253
|
+
# @option attrs [String] :message_id ID that uniquely identifies a
|
254
|
+
# message across the API. (optional)
|
221
255
|
def page(attrs)
|
222
256
|
symbolize_keys! attrs
|
223
257
|
check_user_id! attrs
|
@@ -228,7 +262,7 @@ module Segment
|
|
228
262
|
context = attrs[:context] || {}
|
229
263
|
message_id = attrs[:message_id].to_s if attrs[:message_id]
|
230
264
|
|
231
|
-
|
265
|
+
raise ArgumentError, '.properties must be a hash' unless properties.is_a? Hash
|
232
266
|
isoify_dates! properties
|
233
267
|
|
234
268
|
check_timestamp! timestamp
|
@@ -248,18 +282,24 @@ module Segment
|
|
248
282
|
:type => 'page'
|
249
283
|
})
|
250
284
|
end
|
251
|
-
|
285
|
+
|
286
|
+
# Records a screen view (for a mobile app)
|
252
287
|
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
#
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
260
|
-
#
|
261
|
-
#
|
262
|
-
#
|
288
|
+
# @param [Hash] attrs
|
289
|
+
# @option attrs [String] :anonymous_id ID for a user when you don't know
|
290
|
+
# who they are yet. (optional but you must provide either an
|
291
|
+
# `anonymous_id` or `user_id`)
|
292
|
+
# @option attrs [String] :category The screen category (optional)
|
293
|
+
# @option attrs [Hash] :context ({})
|
294
|
+
# @option attrs [Hash] :integrations What integrations this event
|
295
|
+
# goes to (optional)
|
296
|
+
# @option attrs [String] :name Name of the screen
|
297
|
+
# @option attrs [Hash] :options Options such as user traits (optional)
|
298
|
+
# @option attrs [Hash] :properties Page properties (optional)
|
299
|
+
# @option attrs [Time] :timestamp When the pageview occurred (optional)
|
300
|
+
# @option attrs [String] :user_id The ID of the user viewing the screen
|
301
|
+
# @option attrs [String] :message_id ID that uniquely identifies a
|
302
|
+
# message across the API. (optional)
|
263
303
|
def screen(attrs)
|
264
304
|
symbolize_keys! attrs
|
265
305
|
check_user_id! attrs
|
@@ -270,7 +310,7 @@ module Segment
|
|
270
310
|
context = attrs[:context] || {}
|
271
311
|
message_id = attrs[:message_id].to_s if attrs[:message_id]
|
272
312
|
|
273
|
-
|
313
|
+
raise ArgumentError, '.properties must be a hash' unless properties.is_a? Hash
|
274
314
|
isoify_dates! properties
|
275
315
|
|
276
316
|
check_timestamp! timestamp
|
@@ -291,9 +331,7 @@ module Segment
|
|
291
331
|
})
|
292
332
|
end
|
293
333
|
|
294
|
-
#
|
295
|
-
#
|
296
|
-
# returns Fixnum of messages in the queue
|
334
|
+
# @return [Fixnum] number of messages in the queue
|
297
335
|
def queued_messages
|
298
336
|
@queue.length
|
299
337
|
end
|
@@ -306,11 +344,20 @@ module Segment
|
|
306
344
|
def enqueue(action)
|
307
345
|
# add our request id for tracing purposes
|
308
346
|
action[:messageId] ||= uid
|
309
|
-
|
310
|
-
|
347
|
+
|
348
|
+
if @queue.length < @max_queue_size
|
311
349
|
@queue << action
|
350
|
+
ensure_worker_running
|
351
|
+
|
352
|
+
true
|
353
|
+
else
|
354
|
+
logger.warn(
|
355
|
+
'Queue is full, dropping events. The :max_queue_size ' \
|
356
|
+
'configuration parameter can be increased to prevent this from ' \
|
357
|
+
'happening.'
|
358
|
+
)
|
359
|
+
false
|
312
360
|
end
|
313
|
-
!queue_full
|
314
361
|
end
|
315
362
|
|
316
363
|
# private: Ensures that a string is non-empty
|
@@ -320,7 +367,7 @@ module Segment
|
|
320
367
|
#
|
321
368
|
def check_presence!(obj, name)
|
322
369
|
if obj.nil? || (obj.is_a?(String) && obj.empty?)
|
323
|
-
|
370
|
+
raise ArgumentError, "#{name} must be given"
|
324
371
|
end
|
325
372
|
end
|
326
373
|
|
@@ -328,20 +375,20 @@ module Segment
|
|
328
375
|
#
|
329
376
|
# context - Hash of call context
|
330
377
|
def add_context(context)
|
331
|
-
context[:library] =
|
378
|
+
context[:library] = { :name => 'analytics-ruby', :version => Segment::Analytics::VERSION.to_s }
|
332
379
|
end
|
333
380
|
|
334
381
|
# private: Checks that the write_key is properly initialized
|
335
382
|
def check_write_key!
|
336
|
-
|
383
|
+
raise ArgumentError, 'Write key must be initialized' if @write_key.nil?
|
337
384
|
end
|
338
385
|
|
339
386
|
# private: Checks the timstamp option to make sure it is a Time.
|
340
387
|
def check_timestamp!(timestamp)
|
341
|
-
|
388
|
+
raise ArgumentError, 'Timestamp must be a Time' unless timestamp.is_a? Time
|
342
389
|
end
|
343
390
|
|
344
|
-
def event
|
391
|
+
def event(attrs)
|
345
392
|
symbolize_keys! attrs
|
346
393
|
|
347
394
|
{
|
@@ -354,8 +401,10 @@ module Segment
|
|
354
401
|
}
|
355
402
|
end
|
356
403
|
|
357
|
-
def check_user_id!
|
358
|
-
|
404
|
+
def check_user_id!(attrs)
|
405
|
+
unless attrs[:user_id] || attrs[:anonymous_id]
|
406
|
+
raise ArgumentError, 'Must supply either user_id or anonymous_id'
|
407
|
+
end
|
359
408
|
end
|
360
409
|
|
361
410
|
def ensure_worker_running
|