kameleoon-client-ruby 3.2.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kameleoon/configuration/custom_data_info.rb +16 -8
- data/lib/kameleoon/configuration/data_file.rb +40 -17
- data/lib/kameleoon/configuration/feature_flag.rb +10 -0
- data/lib/kameleoon/configuration/rule.rb +4 -0
- data/lib/kameleoon/configuration/settings.rb +13 -8
- data/lib/kameleoon/configuration/variation_exposition.rb +4 -0
- data/lib/kameleoon/data/browser.rb +4 -0
- data/lib/kameleoon/data/conversion.rb +4 -0
- data/lib/kameleoon/data/cookie.rb +4 -0
- data/lib/kameleoon/data/custom_data.rb +11 -3
- data/lib/kameleoon/data/data.rb +30 -4
- data/lib/kameleoon/data/device.rb +4 -0
- data/lib/kameleoon/data/geolocation.rb +5 -0
- data/lib/kameleoon/data/kcs_heat.rb +16 -0
- data/lib/kameleoon/data/manager/assigned_variation.rb +5 -0
- data/lib/kameleoon/data/manager/data_array_storage.rb +7 -0
- data/lib/kameleoon/data/manager/data_map_storage.rb +7 -0
- data/lib/kameleoon/data/manager/page_view_visit.rb +4 -0
- data/lib/kameleoon/data/manager/visitor.rb +198 -67
- data/lib/kameleoon/data/manager/visitor_manager.rb +54 -17
- data/lib/kameleoon/data/mapping_identifier.rb +33 -0
- data/lib/kameleoon/data/operating_system.rb +4 -0
- data/lib/kameleoon/data/page_view.rb +6 -1
- data/lib/kameleoon/data/unique_identifier.rb +11 -0
- data/lib/kameleoon/data/user_agent.rb +4 -0
- data/lib/kameleoon/data/visitor_visits.rb +12 -1
- data/lib/kameleoon/hybrid/manager.rb +13 -4
- data/lib/kameleoon/kameleoon_client.rb +348 -146
- data/lib/kameleoon/kameleoon_client_config.rb +64 -17
- data/lib/kameleoon/kameleoon_client_factory.rb +15 -2
- data/lib/kameleoon/logging/default_logger.rb +20 -0
- data/lib/kameleoon/logging/kameleoon_logger.rb +77 -0
- data/lib/kameleoon/logging/logger.rb +12 -0
- data/lib/kameleoon/managers/data/data_manager.rb +36 -0
- data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +33 -18
- data/lib/kameleoon/managers/remote_data/remote_visitor_data.rb +42 -16
- data/lib/kameleoon/managers/tracking/tracking_builder.rb +149 -0
- data/lib/kameleoon/managers/tracking/tracking_manager.rb +97 -0
- data/lib/kameleoon/managers/tracking/visitor_tracking_registry.rb +94 -0
- data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +22 -5
- data/lib/kameleoon/network/access_token_source.rb +46 -14
- data/lib/kameleoon/network/cookie/cookie_manager.rb +45 -7
- data/lib/kameleoon/network/net_provider.rb +2 -3
- data/lib/kameleoon/network/network_manager.rb +16 -21
- data/lib/kameleoon/network/request.rb +14 -3
- data/lib/kameleoon/network/response.rb +4 -0
- data/lib/kameleoon/network/url_provider.rb +11 -10
- data/lib/kameleoon/real_time/real_time_configuration_service.rb +10 -11
- data/lib/kameleoon/sdk_version.rb +31 -0
- data/lib/kameleoon/targeting/condition.rb +6 -2
- data/lib/kameleoon/targeting/condition_factory.rb +3 -0
- data/lib/kameleoon/targeting/conditions/browser_condition.rb +3 -3
- data/lib/kameleoon/targeting/conditions/cookie_condition.rb +10 -10
- data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +0 -1
- data/lib/kameleoon/targeting/conditions/kcs_heat_range_condition.rb +37 -0
- data/lib/kameleoon/targeting/conditions/number_condition.rb +4 -4
- data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +1 -2
- data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +2 -1
- data/lib/kameleoon/targeting/conditions/segment_condition.rb +3 -3
- data/lib/kameleoon/targeting/conditions/string_value_condition.rb +2 -1
- data/lib/kameleoon/targeting/conditions/target_feature_flag_condition.rb +7 -11
- data/lib/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.rb +1 -2
- data/lib/kameleoon/targeting/conditions/visit_number_today_condition.rb +4 -4
- data/lib/kameleoon/targeting/conditions/visit_number_total_condition.rb +5 -3
- data/lib/kameleoon/targeting/conditions/visitor_new_return_condition.rb +7 -6
- data/lib/kameleoon/targeting/models.rb +0 -14
- data/lib/kameleoon/targeting/targeting_manager.rb +37 -7
- data/lib/kameleoon/targeting/tree_builder.rb +10 -5
- data/lib/kameleoon/types/remote_visitor_data_filter.rb +21 -3
- data/lib/kameleoon/types/variable.rb +21 -0
- data/lib/kameleoon/types/variation.rb +22 -0
- data/lib/kameleoon/utils.rb +18 -0
- data/lib/kameleoon/version.rb +1 -27
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fb2eefaf6fa7008e5e475044e2f3c20baa088332657f0e19e17c73abffdfa3b
|
4
|
+
data.tar.gz: ef078e7a9d1ac4fd2fef3a74edf4ee5328043b6989c59eafc29559f79ab535d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8df54dcee89dc21a3565948e96b330b655d780ca7cbd4955385b12c5ad64ccdbc8318b17043acb02eddcd2d8dd45191eaeb001d6957e250573e8b9cc606ffbf0
|
7
|
+
data.tar.gz: 3fe4dfe732310de088f45dcc2002c2504b03e45e2e101bb7199b46783cac46aed80a7e35fc0cc6995ddcb7ba0202629d367922e58d8a8e90b974679f91363086
|
@@ -1,25 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'kameleoon/logging/kameleoon_logger'
|
4
|
+
|
3
5
|
module Kameleoon
|
4
6
|
# Module which contains all internal data of SDK
|
5
7
|
module Configuration
|
6
|
-
|
7
8
|
class CustomDataInfo
|
8
9
|
attr_reader :local_only, :visitor_scope, :mapping_identifier_index
|
10
|
+
|
9
11
|
SCOPE_VISITOR = 'VISITOR'
|
10
12
|
|
11
|
-
def initialize(hashes
|
13
|
+
def initialize(hashes)
|
12
14
|
@local_only = Set[]
|
13
15
|
@visitor_scope = Set[]
|
14
|
-
@log_func = log_func
|
15
16
|
unless hashes.nil?
|
16
17
|
for hash in hashes
|
17
18
|
index = hash['index']
|
18
19
|
@local_only.add(index) if hash['localOnly']
|
19
20
|
@visitor_scope.add(index) if hash['scope'] == SCOPE_VISITOR
|
20
21
|
if hash['isMappingIdentifier']
|
21
|
-
|
22
|
-
|
22
|
+
unless @mapping_identifier_index.nil?
|
23
|
+
Logging::KameleoonLogger.warning('More than one mapping identifier is set. Undefined behavior ' \
|
24
|
+
'may occur on cross-device reconciliation.')
|
25
|
+
|
23
26
|
end
|
24
27
|
@mapping_identifier_index = index
|
25
28
|
end
|
@@ -27,17 +30,22 @@ module Kameleoon
|
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
30
|
-
def local_only?
|
33
|
+
def local_only?(index)
|
31
34
|
@local_only.include?(index)
|
32
35
|
end
|
33
36
|
|
34
|
-
def mapping_identifier?
|
37
|
+
def mapping_identifier?(index)
|
35
38
|
index == @mapping_identifier_index
|
36
39
|
end
|
37
40
|
|
38
|
-
def visitor_scope?
|
41
|
+
def visitor_scope?(index)
|
39
42
|
@visitor_scope.include?(index)
|
40
43
|
end
|
44
|
+
|
45
|
+
def self.mapping_identifier?(custom_data_info, custom_data)
|
46
|
+
!custom_data_info.nil? && (custom_data.id == custom_data_info.mapping_identifier_index) && \
|
47
|
+
!(custom_data.values.empty? || custom_data.values[0].empty?)
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
@@ -3,31 +3,32 @@
|
|
3
3
|
require 'kameleoon/configuration/settings'
|
4
4
|
require 'kameleoon/configuration/feature_flag'
|
5
5
|
require 'kameleoon/configuration/custom_data_info'
|
6
|
+
require 'kameleoon/logging/kameleoon_logger'
|
6
7
|
|
7
8
|
module Kameleoon
|
8
9
|
module Configuration
|
9
10
|
class DataFile
|
10
|
-
attr_reader :settings, :feature_flags, :has_any_targeted_delivery_rule, :feature_flag_by_id, :rule_by_segment_id,
|
11
|
+
attr_reader :settings, :feature_flags, :has_any_targeted_delivery_rule, :feature_flag_by_id, :rule_by_segment_id,
|
12
|
+
:variation_by_id, :custom_data_info
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@custom_data_info = Kameleoon::Configuration::CustomDataInfo.new(nil, @log_func)
|
14
|
+
def to_s
|
15
|
+
'DataFile{' \
|
16
|
+
"environment:#{@environment}," \
|
17
|
+
"feature_flags:#{@feature_flags.size}," \
|
18
|
+
"settings:#{@settings}" \
|
19
|
+
'}'
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def initialize(environment, configuration = nil)
|
23
|
+
Logging::KameleoonLogger.debug('CALL: DataFile.new(environment: %s)', environment)
|
24
|
+
@environment = environment
|
25
|
+
if configuration.nil?
|
26
|
+
init_default
|
27
|
+
else
|
28
|
+
init(configuration)
|
26
29
|
end
|
27
|
-
@has_any_targeted_delivery_rule = any_targeted_delivery_rule?
|
28
30
|
collect_indices
|
29
|
-
|
30
|
-
self
|
31
|
+
Logging::KameleoonLogger.debug('RETURN: DataFile.new(environment: %s)', environment)
|
31
32
|
end
|
32
33
|
|
33
34
|
def get_feature_flag(feature_key)
|
@@ -40,6 +41,28 @@ module Kameleoon
|
|
40
41
|
|
41
42
|
private
|
42
43
|
|
44
|
+
def init_default
|
45
|
+
Logging::KameleoonLogger.debug('CALL: DataFile.init_default')
|
46
|
+
@settings = Settings.new
|
47
|
+
@feature_flags = {}
|
48
|
+
@has_any_targeted_delivery_rule = false
|
49
|
+
@custom_data_info = Kameleoon::Configuration::CustomDataInfo.new(nil)
|
50
|
+
Logging::KameleoonLogger.debug('RETURN: DataFile.init_default')
|
51
|
+
end
|
52
|
+
|
53
|
+
def init(configuration)
|
54
|
+
Logging::KameleoonLogger.debug('CALL: DataFile.init(configuration: %s)', configuration)
|
55
|
+
@settings = Settings.new(configuration['configuration'])
|
56
|
+
@feature_flags = {}
|
57
|
+
configuration['featureFlags'].each do |raw|
|
58
|
+
ff = FeatureFlag.new(raw)
|
59
|
+
@feature_flags[ff.feature_key] = ff
|
60
|
+
end
|
61
|
+
@has_any_targeted_delivery_rule = any_targeted_delivery_rule?
|
62
|
+
@custom_data_info = CustomDataInfo.new(configuration['customData'])
|
63
|
+
Logging::KameleoonLogger.debug('RETURN: DataFile.init(configuration: %s)', configuration)
|
64
|
+
end
|
65
|
+
|
43
66
|
def any_targeted_delivery_rule?
|
44
67
|
@feature_flags.any? { |_, ff| ff.environment_enabled && ff.rules.any?(&:targeted_delivery_type?) }
|
45
68
|
end
|
@@ -50,10 +73,10 @@ module Kameleoon
|
|
50
73
|
@variation_by_id = {}
|
51
74
|
|
52
75
|
@feature_flags.each_value do |feature_flag|
|
76
|
+
@feature_flag_by_id[feature_flag.id] = feature_flag
|
53
77
|
next if feature_flag.rules.nil?
|
54
78
|
|
55
79
|
feature_flag.rules.each do |rule|
|
56
|
-
@feature_flag_by_id[feature_flag.id] = feature_flag
|
57
80
|
@rule_by_segment_id[rule.segment_id] = rule
|
58
81
|
rule.variation_by_exposition.each do |variation|
|
59
82
|
@variation_by_id[variation.variation_id] = variation
|
@@ -14,6 +14,16 @@ module Kameleoon
|
|
14
14
|
array&.map { |it| FeatureFlag.new(it) }
|
15
15
|
end
|
16
16
|
|
17
|
+
def to_s
|
18
|
+
'FeatureFlag{' \
|
19
|
+
"id:#{@id}, " \
|
20
|
+
"feature_key:#{@feature_key}, " \
|
21
|
+
"environment_enabled:#{@environment_enabled}, " \
|
22
|
+
"default_variation_key:#{@default_variation_key}, " \
|
23
|
+
"rules:#{@rules.size}" \
|
24
|
+
'}'
|
25
|
+
end
|
26
|
+
|
17
27
|
def initialize(hash)
|
18
28
|
@id = hash['id']
|
19
29
|
@feature_key = hash['featureKey']
|
@@ -9,16 +9,21 @@ module Kameleoon
|
|
9
9
|
attr_accessor :real_time_update
|
10
10
|
attr_reader :is_consent_required, :data_api_domain
|
11
11
|
|
12
|
-
def
|
13
|
-
@real_time_update
|
14
|
-
|
15
|
-
@data_api_domain = nil
|
12
|
+
def to_s
|
13
|
+
"Settings{real_time_update:#{@real_time_update},is_consent_required:#{@is_consent_required}," \
|
14
|
+
"data_api_domain:#{@data_api_domain}}"
|
16
15
|
end
|
17
16
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
def initialize(configuration = nil)
|
18
|
+
if configuration.nil?
|
19
|
+
@real_time_update = false
|
20
|
+
@is_consent_required = false
|
21
|
+
@data_api_domain = nil
|
22
|
+
else
|
23
|
+
@real_time_update = configuration['realTimeUpdate'] || false
|
24
|
+
@is_consent_required = configuration['consentType'] == 'REQUIRED'
|
25
|
+
@data_api_domain = configuration['dataApiDomain']
|
26
|
+
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -11,6 +11,10 @@ module Kameleoon
|
|
11
11
|
array&.map { |it| VariationByExposition.new(it) }
|
12
12
|
end
|
13
13
|
|
14
|
+
def to_s
|
15
|
+
"VariationByExposition{exposition:#{@exposition},variation_key:#{@variation_key},variation_id:#{@variation_id}}"
|
16
|
+
end
|
17
|
+
|
14
18
|
def initialize(hash)
|
15
19
|
@variation_key = hash['variationKey']
|
16
20
|
@variation_id = hash['variationId']
|
@@ -37,6 +37,10 @@ module Kameleoon
|
|
37
37
|
class Browser < DuplicationUnsafeData
|
38
38
|
attr_reader :type, :version
|
39
39
|
|
40
|
+
def to_s
|
41
|
+
"Browser{type:#{@type},version:#{@version}}"
|
42
|
+
end
|
43
|
+
|
40
44
|
# @param [BrowserType] browser_type Browser type, can be: CHROME, INTERNET_EXPLORER, FIREFOX, SAFARI, OPERA, OTHER
|
41
45
|
# @param [float] version Version of browser
|
42
46
|
def initialize(browser_type, version = Float::NAN)
|
@@ -9,6 +9,10 @@ module Kameleoon
|
|
9
9
|
class Conversion < DuplicationSafeData
|
10
10
|
attr_reader :goal_id, :revenue, :negative
|
11
11
|
|
12
|
+
def to_s
|
13
|
+
"Conversion{goal_id:#{@goal_id},revenue:#{@revenue},negative:#{@negative}}"
|
14
|
+
end
|
15
|
+
|
12
16
|
# @param [Integer] goal_id Id of the goal associated to the conversion
|
13
17
|
# @param [Float] revenue Optional field - Revenue associated to the conversion.
|
14
18
|
# @param [Boolean] negative Optional field - If the revenue is negative. By default it's positive.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
|
+
require 'kameleoon/logging/kameleoon_logger'
|
4
5
|
require 'kameleoon/network/uri_helper'
|
5
6
|
require_relative 'data'
|
6
7
|
|
@@ -8,7 +9,10 @@ module Kameleoon
|
|
8
9
|
# Represents any custom data for targeting conditions
|
9
10
|
class CustomData < DuplicationUnsafeData
|
10
11
|
attr_reader :id, :values
|
11
|
-
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"CustomData{id:#{@id},values:#{@values}}"
|
15
|
+
end
|
12
16
|
|
13
17
|
# @param [Integer] id Id of the custom data
|
14
18
|
# @param [String] value Value of the custom data
|
@@ -33,9 +37,14 @@ module Kameleoon
|
|
33
37
|
@id = arg0
|
34
38
|
@values = args
|
35
39
|
end
|
40
|
+
|
41
|
+
if @values.empty?
|
42
|
+
Logging::KameleoonLogger.error('Created a custom data %s with no values. It will not be tracked.', @id)
|
43
|
+
end
|
44
|
+
|
36
45
|
return if @id.is_a?(Integer)
|
37
46
|
|
38
|
-
|
47
|
+
Logging::KameleoonLogger.warning("CustomData field 'id' must be of 'Integer' type")
|
39
48
|
@id = @id.is_a?(String) ? @id.to_i : -1
|
40
49
|
end
|
41
50
|
# rubocop:enable Metrics/MethodLength
|
@@ -51,7 +60,6 @@ module Kameleoon
|
|
51
60
|
overwrite: 'true',
|
52
61
|
nonce: nonce
|
53
62
|
}
|
54
|
-
params[:mappingIdentifier] = is_mapping_identifier if is_mapping_identifier
|
55
63
|
Kameleoon::Network::UriHelper.encode_query(params)
|
56
64
|
end
|
57
65
|
end
|
data/lib/kameleoon/data/data.rb
CHANGED
@@ -18,21 +18,47 @@ module Kameleoon
|
|
18
18
|
GEOLOCATION = 'GEOLOCATION'
|
19
19
|
end
|
20
20
|
|
21
|
+
module DataState
|
22
|
+
UNSENT = 0
|
23
|
+
TRANSMITTING = 1
|
24
|
+
SENT = 2
|
25
|
+
end
|
26
|
+
|
21
27
|
# Represents base class for any Kameleoon data
|
22
28
|
class Data
|
23
|
-
attr_reader :instance
|
29
|
+
attr_reader :instance
|
24
30
|
|
25
31
|
def initialize(data_type)
|
26
32
|
@instance = data_type
|
27
|
-
@
|
33
|
+
@state = DataState::UNSENT
|
28
34
|
end
|
29
35
|
|
30
36
|
def obtain_full_post_text_line
|
31
37
|
raise KameleoonError.new('ToDo: implement this method.'), 'ToDo: implement this method.'
|
32
38
|
end
|
33
39
|
|
40
|
+
def unsent
|
41
|
+
@state == DataState::UNSENT
|
42
|
+
end
|
43
|
+
|
44
|
+
def transmitting
|
45
|
+
@state == DataState::TRANSMITTING
|
46
|
+
end
|
47
|
+
|
48
|
+
def sent
|
49
|
+
@state == DataState::SENT
|
50
|
+
end
|
51
|
+
|
52
|
+
def mark_as_unsent
|
53
|
+
@state = DataState::UNSENT if transmitting
|
54
|
+
end
|
55
|
+
|
56
|
+
def mark_as_transmitting
|
57
|
+
@state = DataState::TRANSMITTING if unsent
|
58
|
+
end
|
59
|
+
|
34
60
|
def mark_as_sent
|
35
|
-
@
|
61
|
+
@state = DataState::SENT
|
36
62
|
@nonce = nil
|
37
63
|
end
|
38
64
|
end
|
@@ -52,7 +78,7 @@ module Kameleoon
|
|
52
78
|
private
|
53
79
|
|
54
80
|
def nonce
|
55
|
-
@nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH) if
|
81
|
+
@nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH) if !sent && @nonce.nil?
|
56
82
|
@nonce
|
57
83
|
end
|
58
84
|
end
|
@@ -5,6 +5,11 @@ module Kameleoon
|
|
5
5
|
class Geolocation < DuplicationUnsafeData
|
6
6
|
attr_reader :country, :region, :city, :postal_code, :latitude, :longitude
|
7
7
|
|
8
|
+
def to_s
|
9
|
+
"Geolocation{country:'#{@country}',region:'#{@region}',city:'#{@city}',postal_code:'#{@postal_code}'," \
|
10
|
+
"latitude:#{@latitude},longitude:#{@longitude}}"
|
11
|
+
end
|
12
|
+
|
8
13
|
# @param [String] country Country of visitor's geolocation. Required
|
9
14
|
# @param [String] region Region of visitor's geolocation. Optional
|
10
15
|
# @param [String] city City of visitor's geolocation. Optional
|
@@ -13,6 +13,11 @@ module Kameleoon
|
|
13
13
|
|
14
14
|
attr_reader :experiment_id, :variation_id, :rule_type, :assignment_time
|
15
15
|
|
16
|
+
def to_s
|
17
|
+
"AssignedVariation{experiment_id:#{@experiment_id},variation_id:#{@variation_id}," \
|
18
|
+
"assignment_time:#{@assignment_time},rule_type:#{@rule_type}}"
|
19
|
+
end
|
20
|
+
|
16
21
|
def initialize(experiment_id, variation_id, rule_type = Kameleoon::Configuration::RuleType::UNKNOWN, assignment_time: nil)
|
17
22
|
super(DataType::ASSIGNED_VARIATION)
|
18
23
|
@experiment_id = experiment_id
|
@@ -6,6 +6,13 @@ module Kameleoon
|
|
6
6
|
# DataArrayStorage is a readonly accessor to a sequntial storage of specific visitor data.
|
7
7
|
# It is thread-safe
|
8
8
|
class DataArrayStorage
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
values = []
|
12
|
+
enumerate { |v| values << v }
|
13
|
+
"DataArrayStorage{values:#{values.join(',')}}"
|
14
|
+
end
|
15
|
+
|
9
16
|
def initialize(mutex, array)
|
10
17
|
@mutex = mutex
|
11
18
|
@array = array
|
@@ -6,6 +6,13 @@ module Kameleoon
|
|
6
6
|
# DataMapStorage is a readonly accessor to a key-value based storage of specific visitor data.
|
7
7
|
# It is thread-safe
|
8
8
|
class DataMapStorage
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
values = []
|
12
|
+
enumerate { |v| values << v }
|
13
|
+
"DataMapStorage{values:#{values.join(',')}}"
|
14
|
+
end
|
15
|
+
|
9
16
|
def initialize(mutex, map)
|
10
17
|
@mutex = mutex
|
11
18
|
@map = map
|
@@ -5,6 +5,10 @@ module Kameleoon
|
|
5
5
|
class PageViewVisit
|
6
6
|
attr_reader :page_view, :count, :last_timestamp
|
7
7
|
|
8
|
+
def to_s
|
9
|
+
"PageViewVisit{last_timestamp:#{@last_timestamp},count:#{@count},page_view:#{@page_view}}"
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(page_view, count = 1, timestamp = nil)
|
9
13
|
@page_view = page_view
|
10
14
|
@count = count
|