splitclient-rb 1.0.2.wip → 8.11.1.pre.rc1-java
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/.github/CODEOWNERS +1 -0
- data/.github/pull_request_template.md +9 -0
- data/.github/workflows/ci.yml +90 -0
- data/.github/workflows/update-license-year.yml +45 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +76 -0
- data/.simplecov +1 -0
- data/CHANGES.txt +361 -2
- data/CONTRIBUTORS-GUIDE.md +49 -0
- data/Gemfile +2 -0
- data/LICENSE +3 -36
- data/NOTICE.txt +5 -0
- data/README.md +59 -127
- data/Rakefile +27 -3
- data/ext/murmurhash/MurmurHash3.java +302 -0
- data/gemfiles/faraday_after_0.13.gemfile +7 -0
- data/gemfiles/faraday_before_0.13.gemfile +8 -0
- data/lib/murmurhash/base.rb +58 -0
- data/lib/murmurhash/murmurhash.jar +0 -0
- data/lib/murmurhash/murmurhash_mri.rb +3 -0
- data/lib/splitclient-rb/cache/adapters/cache_adapter.rb +130 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapter.rb +12 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +137 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +53 -0
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +178 -0
- data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +83 -0
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +70 -0
- data/lib/splitclient-rb/cache/filter/bloom_filter.rb +67 -0
- data/lib/splitclient-rb/cache/filter/filter_adapter.rb +32 -0
- data/lib/splitclient-rb/cache/filter/flag_set_filter.rb +40 -0
- data/lib/splitclient-rb/cache/hashers/impression_hasher.rb +34 -0
- data/lib/splitclient-rb/cache/observers/impression_observer.rb +22 -0
- data/lib/splitclient-rb/cache/observers/noop_impression_observer.rb +10 -0
- data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +45 -0
- data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +35 -0
- data/lib/splitclient-rb/cache/repositories/events_repository.rb +61 -0
- data/lib/splitclient-rb/cache/repositories/flag_sets/memory_repository.rb +40 -0
- data/lib/splitclient-rb/cache/repositories/flag_sets/redis_repository.rb +49 -0
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +56 -0
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +57 -0
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +23 -0
- data/lib/splitclient-rb/cache/repositories/repository.rb +24 -0
- data/lib/splitclient-rb/cache/repositories/rule_based_segments_repository.rb +136 -0
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +124 -0
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +296 -0
- data/lib/splitclient-rb/cache/routers/impression_router.rb +60 -0
- data/lib/splitclient-rb/cache/senders/events_sender.rb +42 -0
- data/lib/splitclient-rb/cache/senders/impressions_adapter/memory_sender.rb +71 -0
- data/lib/splitclient-rb/cache/senders/impressions_adapter/redis_sender.rb +69 -0
- data/lib/splitclient-rb/cache/senders/impressions_count_sender.rb +43 -0
- data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +95 -0
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +52 -0
- data/lib/splitclient-rb/cache/senders/impressions_sender_adapter.rb +21 -0
- data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +47 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_builder.rb +95 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +110 -0
- data/lib/splitclient-rb/cache/stores/store_utils.rb +13 -0
- data/lib/splitclient-rb/clients/split_client.rb +530 -0
- data/lib/splitclient-rb/constants.rb +16 -0
- data/lib/splitclient-rb/engine/api/client.rb +87 -0
- data/lib/splitclient-rb/engine/api/events.rb +57 -0
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +58 -0
- data/lib/splitclient-rb/engine/api/impressions.rb +79 -0
- data/lib/splitclient-rb/engine/api/segments.rb +78 -0
- data/lib/splitclient-rb/engine/api/splits.rb +139 -0
- data/lib/splitclient-rb/engine/api/telemetry_api.rb +47 -0
- data/lib/splitclient-rb/engine/auth_api_client.rb +100 -0
- data/lib/splitclient-rb/engine/back_off.rb +26 -0
- data/lib/splitclient-rb/engine/common/impressions_counter.rb +45 -0
- data/lib/splitclient-rb/engine/common/impressions_manager.rb +165 -0
- data/lib/splitclient-rb/engine/common/noop_impressions_counter.rb +27 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/evaluator/splitter.rb +35 -22
- data/lib/splitclient-rb/engine/events/events_delivery.rb +20 -0
- data/lib/splitclient-rb/engine/events/events_manager.rb +194 -0
- data/lib/splitclient-rb/engine/events/events_manager_config.rb +96 -0
- data/lib/splitclient-rb/engine/events/events_task.rb +50 -0
- data/lib/splitclient-rb/engine/events/noop_events_queue.rb +13 -0
- data/lib/splitclient-rb/engine/fallback_treatment_calculator.rb +48 -0
- data/lib/splitclient-rb/engine/impressions/noop_unique_keys_tracker.rb +17 -0
- data/lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb +144 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/matchers/all_keys_matcher.rb +10 -21
- data/lib/splitclient-rb/engine/matchers/between_matcher.rb +47 -0
- data/lib/splitclient-rb/engine/matchers/between_semver_matcher.rb +33 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/matchers/combiners.rb +4 -6
- data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +80 -0
- data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +20 -0
- data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +16 -0
- data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +43 -0
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +26 -0
- data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +42 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +37 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +44 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +16 -0
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +43 -0
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/in_list_semver_matcher.rb +36 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +43 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/matcher.rb +52 -0
- data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +29 -0
- data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +47 -0
- data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +22 -0
- data/lib/splitclient-rb/engine/matchers/prerequisites_matcher.rb +31 -0
- data/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb +78 -0
- data/lib/splitclient-rb/engine/matchers/semver.rb +201 -0
- data/lib/splitclient-rb/engine/matchers/set_matcher.rb +27 -0
- data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +40 -0
- data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +66 -0
- data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +66 -0
- data/lib/splitclient-rb/engine/models/evaluation_options.rb +9 -0
- data/lib/splitclient-rb/engine/models/event_active_subscriptions.rb +14 -0
- data/lib/splitclient-rb/engine/models/events_metadata.rb +10 -0
- data/lib/splitclient-rb/engine/models/fallback_treatment.rb +11 -0
- data/lib/splitclient-rb/engine/models/fallback_treatments_configuration.rb +36 -0
- data/lib/splitclient-rb/engine/models/label.rb +10 -0
- data/lib/splitclient-rb/engine/models/sdk_event.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_event_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event.rb +8 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb +16 -0
- data/lib/splitclient-rb/engine/models/segment_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/split.rb +17 -0
- data/lib/splitclient-rb/engine/models/split_http_response.rb +19 -0
- data/lib/splitclient-rb/engine/models/treatment.rb +3 -0
- data/lib/splitclient-rb/engine/models/valid_sdk_event.rb +14 -0
- data/lib/splitclient-rb/engine/parser/condition.rb +271 -0
- data/lib/splitclient-rb/engine/parser/evaluator.rb +112 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/parser/partition.rb +2 -4
- data/lib/splitclient-rb/engine/push_manager.rb +66 -0
- data/lib/splitclient-rb/engine/status_manager.rb +39 -0
- data/lib/splitclient-rb/engine/sync_manager.rb +183 -0
- data/lib/splitclient-rb/engine/synchronizer.rb +231 -0
- data/lib/splitclient-rb/exceptions.rb +26 -0
- data/lib/splitclient-rb/helpers/decryption_helper.rb +25 -0
- data/lib/splitclient-rb/helpers/evaluator_helper.rb +37 -0
- data/lib/splitclient-rb/helpers/repository_helper.rb +61 -0
- data/lib/splitclient-rb/helpers/thread_helper.rb +24 -0
- data/lib/splitclient-rb/helpers/util.rb +26 -0
- data/lib/splitclient-rb/managers/split_manager.rb +121 -0
- data/lib/splitclient-rb/spec.rb +9 -0
- data/lib/splitclient-rb/split_config.rb +591 -47
- data/lib/splitclient-rb/split_factory.rb +284 -0
- data/lib/splitclient-rb/split_factory_builder.rb +7 -0
- data/lib/splitclient-rb/split_factory_registry.rb +63 -0
- data/lib/splitclient-rb/split_logger.rb +23 -0
- data/lib/splitclient-rb/sse/event_source/client.rb +264 -0
- data/lib/splitclient-rb/sse/event_source/event_parser.rb +65 -0
- data/lib/splitclient-rb/sse/event_source/event_types.rb +15 -0
- data/lib/splitclient-rb/sse/event_source/stream_data.rb +22 -0
- data/lib/splitclient-rb/sse/notification_manager_keeper.rb +84 -0
- data/lib/splitclient-rb/sse/notification_processor.rb +48 -0
- data/lib/splitclient-rb/sse/sse_handler.rb +44 -0
- data/lib/splitclient-rb/sse/workers/segments_worker.rb +62 -0
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +153 -0
- data/lib/splitclient-rb/telemetry/domain/constants.rb +48 -0
- data/lib/splitclient-rb/telemetry/domain/structs.rb +35 -0
- data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
- data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
- data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
- data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
- data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
- data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
- data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
- data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +119 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +87 -0
- data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +213 -0
- data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
- data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
- data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +27 -0
- data/lib/splitclient-rb/telemetry/runtime_consumer.rb +25 -0
- data/lib/splitclient-rb/telemetry/runtime_producer.rb +25 -0
- data/lib/splitclient-rb/telemetry/storages/memory.rb +159 -0
- data/lib/splitclient-rb/telemetry/sync_task.rb +36 -0
- data/lib/splitclient-rb/telemetry/synchronizer.rb +33 -0
- data/lib/splitclient-rb/utilitites.rb +49 -0
- data/lib/splitclient-rb/validators.rb +361 -0
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +177 -25
- data/sonar-project.properties +6 -0
- data/splitclient-rb.gemspec +53 -26
- data/tasks/benchmark_get_treatment.rake +31 -17
- data/tasks/irb.rake +6 -0
- metadata +411 -86
- data/NEWS +0 -9
- data/lib/splitclient-cache/local_store.rb +0 -45
- data/lib/splitclient-engine/impressions/impressions.rb +0 -79
- data/lib/splitclient-engine/matchers/between_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/combining_matcher.rb +0 -94
- data/lib/splitclient-engine/matchers/equal_to_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/greater_than_or_equal_to_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/less_than_or_equal_to_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/negation_matcher.rb +0 -54
- data/lib/splitclient-engine/matchers/user_defined_segment_matcher.rb +0 -61
- data/lib/splitclient-engine/matchers/whitelist_matcher.rb +0 -64
- data/lib/splitclient-engine/metrics/binary_search_latency_tracker.rb +0 -122
- data/lib/splitclient-engine/metrics/metrics.rb +0 -158
- data/lib/splitclient-engine/parser/condition.rb +0 -143
- data/lib/splitclient-engine/parser/segment.rb +0 -84
- data/lib/splitclient-engine/parser/segment_parser.rb +0 -46
- data/lib/splitclient-engine/parser/split.rb +0 -68
- data/lib/splitclient-engine/parser/split_adapter.rb +0 -433
- data/lib/splitclient-engine/parser/split_parser.rb +0 -139
- data/lib/splitclient-engine/partitions/treatments.rb +0 -40
- data/lib/splitclient-rb/split_client.rb +0 -156
- data/lib/splitclient-rb_utilitites.rb +0 -26
- data/tasks/console.rake +0 -4
- data/tasks/rspec.rake +0 -3
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Telemetry
|
|
5
|
+
module Storages
|
|
6
|
+
class Memory
|
|
7
|
+
attr_reader :latencies,
|
|
8
|
+
:exceptions,
|
|
9
|
+
:factory_counters,
|
|
10
|
+
:tags,
|
|
11
|
+
:impressions_data_records,
|
|
12
|
+
:events_data_records,
|
|
13
|
+
:last_synchronization,
|
|
14
|
+
:http_errors,
|
|
15
|
+
:http_latencies,
|
|
16
|
+
:auth_rejections,
|
|
17
|
+
:token_refreshes,
|
|
18
|
+
:streaming_events,
|
|
19
|
+
:session_length,
|
|
20
|
+
:updates_from_sse
|
|
21
|
+
|
|
22
|
+
def initialize
|
|
23
|
+
init_latencies
|
|
24
|
+
init_exceptions
|
|
25
|
+
init_factory_counters
|
|
26
|
+
init_impressions_data_records
|
|
27
|
+
init_events_data_records
|
|
28
|
+
init_last_synchronization
|
|
29
|
+
init_http_errors
|
|
30
|
+
init_http_latencies
|
|
31
|
+
init_auth_rejections
|
|
32
|
+
init_token_refreshes
|
|
33
|
+
init_streaming_events
|
|
34
|
+
init_session_length
|
|
35
|
+
init_tags
|
|
36
|
+
init_updates_from_sse
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def init_latencies
|
|
40
|
+
@latencies = Concurrent::Array.new
|
|
41
|
+
treatment_with_config_by_flag_set_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET
|
|
42
|
+
treatment_with_config_by_flag_sets_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS
|
|
43
|
+
|
|
44
|
+
array_size = BinarySearchLatencyTracker::BUCKETS.length
|
|
45
|
+
@latencies << { method: Domain::Constants::TREATMENT, latencies: Concurrent::Array.new(array_size, 0) }
|
|
46
|
+
@latencies << { method: Domain::Constants::TREATMENTS, latencies: Concurrent::Array.new(array_size, 0) }
|
|
47
|
+
@latencies << { method: Domain::Constants::TREATMENT_WITH_CONFIG, latencies: Concurrent::Array.new(array_size, 0) }
|
|
48
|
+
@latencies << { method: Domain::Constants::TREATMENTS_WITH_CONFIG, latencies: Concurrent::Array.new(array_size, 0) }
|
|
49
|
+
@latencies << { method: Domain::Constants::TREATMENTS_BY_FLAG_SET, latencies: Concurrent::Array.new(array_size, 0) }
|
|
50
|
+
@latencies << { method: Domain::Constants::TREATMENTS_BY_FLAG_SETS, latencies: Concurrent::Array.new(array_size, 0) }
|
|
51
|
+
@latencies << { method: treatment_with_config_by_flag_set_const, latencies: Concurrent::Array.new(array_size, 0) }
|
|
52
|
+
@latencies << { method: treatment_with_config_by_flag_sets_const, latencies: Concurrent::Array.new(array_size, 0) }
|
|
53
|
+
@latencies << { method: Domain::Constants::TRACK, latencies: Concurrent::Array.new(array_size, 0) }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def init_exceptions
|
|
57
|
+
@exceptions = Concurrent::Array.new
|
|
58
|
+
treatment_with_config_by_flag_set_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET
|
|
59
|
+
treatment_with_config_by_flag_sets_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS
|
|
60
|
+
|
|
61
|
+
@exceptions << { method: Domain::Constants::TREATMENT, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
62
|
+
@exceptions << { method: Domain::Constants::TREATMENTS, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
63
|
+
@exceptions << { method: Domain::Constants::TREATMENT_WITH_CONFIG, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
64
|
+
@exceptions << { method: Domain::Constants::TREATMENTS_WITH_CONFIG, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
65
|
+
@exceptions << { method: Domain::Constants::TREATMENTS_BY_FLAG_SET, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
66
|
+
@exceptions << { method: Domain::Constants::TREATMENTS_BY_FLAG_SETS, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
67
|
+
@exceptions << { method: treatment_with_config_by_flag_set_const, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
68
|
+
@exceptions << { method: treatment_with_config_by_flag_sets_const, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
69
|
+
@exceptions << { method: Domain::Constants::TRACK, exceptions: Concurrent::AtomicFixnum.new(0) }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def init_factory_counters
|
|
73
|
+
@factory_counters = Concurrent::Array.new
|
|
74
|
+
|
|
75
|
+
@factory_counters << { action: Domain::Constants::BUR_TIMEOUT, counts: Concurrent::AtomicFixnum.new(0) }
|
|
76
|
+
@factory_counters << { action: Domain::Constants::NON_READY_USAGES, counts: Concurrent::AtomicFixnum.new(0) }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def init_impressions_data_records
|
|
80
|
+
@impressions_data_records = Concurrent::Array.new
|
|
81
|
+
|
|
82
|
+
@impressions_data_records << { type: Domain::Constants::IMPRESSIONS_DEDUPE, value: Concurrent::AtomicFixnum.new(0) }
|
|
83
|
+
@impressions_data_records << { type: Domain::Constants::IMPRESSIONS_DROPPED, value: Concurrent::AtomicFixnum.new(0) }
|
|
84
|
+
@impressions_data_records << { type: Domain::Constants::IMPRESSIONS_QUEUED, value: Concurrent::AtomicFixnum.new(0) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def init_events_data_records
|
|
88
|
+
@events_data_records = Concurrent::Array.new
|
|
89
|
+
|
|
90
|
+
@events_data_records << { type: Domain::Constants::EVENTS_DROPPED, value: Concurrent::AtomicFixnum.new(0) }
|
|
91
|
+
@events_data_records << { type: Domain::Constants::EVENTS_QUEUED, value: Concurrent::AtomicFixnum.new(0) }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def init_last_synchronization
|
|
95
|
+
@last_synchronization = Concurrent::Array.new
|
|
96
|
+
|
|
97
|
+
@last_synchronization << { type: Domain::Constants::SPLIT_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
98
|
+
@last_synchronization << { type: Domain::Constants::SEGMENT_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
99
|
+
@last_synchronization << { type: Domain::Constants::EVENT_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
100
|
+
@last_synchronization << { type: Domain::Constants::IMPRESSION_COUNT_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
101
|
+
@last_synchronization << { type: Domain::Constants::IMPRESSIONS_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
102
|
+
@last_synchronization << { type: Domain::Constants::TELEMETRY_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
103
|
+
@last_synchronization << { type: Domain::Constants::TOKEN_SYNC, value: Concurrent::AtomicFixnum.new(0) }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def init_tags
|
|
107
|
+
@tags = Concurrent::Array.new
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def init_http_errors
|
|
111
|
+
@http_errors = Concurrent::Array.new
|
|
112
|
+
|
|
113
|
+
@http_errors << { type: Domain::Constants::SPLIT_SYNC, value: Concurrent::Hash.new }
|
|
114
|
+
@http_errors << { type: Domain::Constants::SEGMENT_SYNC, value: Concurrent::Hash.new }
|
|
115
|
+
@http_errors << { type: Domain::Constants::EVENT_SYNC, value: Concurrent::Hash.new }
|
|
116
|
+
@http_errors << { type: Domain::Constants::IMPRESSION_COUNT_SYNC, value: Concurrent::Hash.new }
|
|
117
|
+
@http_errors << { type: Domain::Constants::IMPRESSIONS_SYNC, value: Concurrent::Hash.new }
|
|
118
|
+
@http_errors << { type: Domain::Constants::TELEMETRY_SYNC, value: Concurrent::Hash.new }
|
|
119
|
+
@http_errors << { type: Domain::Constants::TOKEN_SYNC, value: Concurrent::Hash.new }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def init_http_latencies
|
|
123
|
+
@http_latencies = Concurrent::Array.new
|
|
124
|
+
|
|
125
|
+
array_size = BinarySearchLatencyTracker::BUCKETS.length
|
|
126
|
+
@http_latencies << { type: Domain::Constants::SPLIT_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
127
|
+
@http_latencies << { type: Domain::Constants::SEGMENT_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
128
|
+
@http_latencies << { type: Domain::Constants::EVENT_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
129
|
+
@http_latencies << { type: Domain::Constants::IMPRESSION_COUNT_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
130
|
+
@http_latencies << { type: Domain::Constants::IMPRESSIONS_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
131
|
+
@http_latencies << { type: Domain::Constants::TELEMETRY_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
132
|
+
@http_latencies << { type: Domain::Constants::TOKEN_SYNC, value: Concurrent::Array.new(array_size, 0) }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def init_auth_rejections
|
|
136
|
+
@auth_rejections = Concurrent::AtomicFixnum.new(0)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def init_token_refreshes
|
|
140
|
+
@token_refreshes = Concurrent::AtomicFixnum.new(0)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def init_streaming_events
|
|
144
|
+
@streaming_events = Concurrent::Array.new
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def init_session_length
|
|
148
|
+
@session_length = Concurrent::AtomicFixnum.new(0)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def init_updates_from_sse
|
|
152
|
+
@updates_from_sse = Concurrent::Hash.new
|
|
153
|
+
|
|
154
|
+
@updates_from_sse[Domain::Constants::SPLITS] = 0
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Telemetry
|
|
5
|
+
class SyncTask
|
|
6
|
+
def initialize(config, telemetry_synchronizer)
|
|
7
|
+
@config = config
|
|
8
|
+
@telemetry_synchronizer = telemetry_synchronizer
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call
|
|
12
|
+
stats_thread
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def stats_thread
|
|
18
|
+
@config.threads[:telemetry_stats_sender] = Thread.new { telemetry_sync_task }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def telemetry_sync_task
|
|
22
|
+
@config.logger.info('Starting Telemetry Sync Task')
|
|
23
|
+
|
|
24
|
+
loop do
|
|
25
|
+
sleep(@config.telemetry_refresh_rate)
|
|
26
|
+
|
|
27
|
+
@telemetry_synchronizer.synchronize_stats
|
|
28
|
+
end
|
|
29
|
+
rescue SplitIoClient::SDKShutdownException
|
|
30
|
+
@telemetry_synchronizer.synchronize_stats
|
|
31
|
+
|
|
32
|
+
@config.logger.info('Posting Telemetry due to shutdown')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Telemetry
|
|
5
|
+
class Synchronizer
|
|
6
|
+
extend Forwardable
|
|
7
|
+
def_delegators :@synchronizer,
|
|
8
|
+
:synchronize_config,
|
|
9
|
+
:synchronize_stats
|
|
10
|
+
|
|
11
|
+
def initialize(config,
|
|
12
|
+
telemtry_consumers,
|
|
13
|
+
telemetry_init_producer,
|
|
14
|
+
repositories,
|
|
15
|
+
telemetry_api,
|
|
16
|
+
flag_sets,
|
|
17
|
+
flag_sets_invalid)
|
|
18
|
+
@synchronizer = case config.telemetry_adapter.class.to_s
|
|
19
|
+
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
|
20
|
+
SplitIoClient::Telemetry::RedisSynchronizer.new(config,
|
|
21
|
+
telemetry_init_producer)
|
|
22
|
+
else
|
|
23
|
+
SplitIoClient::Telemetry::MemorySynchronizer.new(config,
|
|
24
|
+
telemtry_consumers,
|
|
25
|
+
repositories,
|
|
26
|
+
telemetry_api,
|
|
27
|
+
flag_sets,
|
|
28
|
+
flag_sets_invalid)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
module Utilities
|
|
3
|
+
extend self
|
|
4
|
+
|
|
5
|
+
# Convert String with Time info to its epoch FixNum previously setting to zero the seconds
|
|
6
|
+
def to_epoch(value)
|
|
7
|
+
parsed = Time.parse(value)
|
|
8
|
+
zeroed = Time.new(parsed.year, parsed.month, parsed.day, parsed.hour, parsed.min, 0, 0)
|
|
9
|
+
|
|
10
|
+
zeroed.to_i
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_epoch_milis(value)
|
|
14
|
+
to_epoch(value) * 1000
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_milis_zero_out_from_seconds(value)
|
|
18
|
+
parsed_value = Time.strptime(value.to_s, '%s').utc
|
|
19
|
+
zeroed = Time.new(parsed_value.year, parsed_value.month, parsed_value.day, parsed_value.hour, parsed_value.min, 0, 0)
|
|
20
|
+
|
|
21
|
+
zeroed.to_i * 1000
|
|
22
|
+
rescue StandardError
|
|
23
|
+
return :non_valid_date_info
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_milis_zero_out_from_hour(value)
|
|
27
|
+
parsed_value = Time.strptime(value.to_s, '%s').utc
|
|
28
|
+
zeroed = Time.new(parsed_value.year, parsed_value.month, parsed_value.day, 0, 0, 0, 0)
|
|
29
|
+
|
|
30
|
+
zeroed.to_i * 1000
|
|
31
|
+
rescue StandardError
|
|
32
|
+
return :non_valid_date_info
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def randomize_interval(interval)
|
|
36
|
+
random_factor = Random.new.rand(50..100) / 100.0
|
|
37
|
+
|
|
38
|
+
interval * random_factor
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def split_bulk_to_send(items, divisions)
|
|
42
|
+
to_return = []
|
|
43
|
+
items.to_a.each_slice(divisions) {|bulk|
|
|
44
|
+
to_return.push(bulk.to_set)
|
|
45
|
+
}
|
|
46
|
+
to_return
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class Validators
|
|
5
|
+
|
|
6
|
+
Flagset_regex = /^[a-z0-9][_a-z0-9]{0,49}$/
|
|
7
|
+
Fallback_treatment_regex = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/
|
|
8
|
+
Fallback_treatment_size = 100
|
|
9
|
+
|
|
10
|
+
def initialize(config)
|
|
11
|
+
@config = config
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def valid_get_treatment_parameters(method, key, split_name, matching_key, bucketing_key, attributes)
|
|
15
|
+
valid_key?(method, key) &&
|
|
16
|
+
valid_split_name?(method, split_name) &&
|
|
17
|
+
valid_matching_key?(method, matching_key) &&
|
|
18
|
+
valid_bucketing_key?(method, key, bucketing_key) &&
|
|
19
|
+
valid_attributes?(method, attributes)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def valid_get_treatments_parameters(method, key, split_names, matching_key, bucketing_key, attributes)
|
|
23
|
+
valid_key?(method, key) &&
|
|
24
|
+
valid_split_names?(method, split_names)
|
|
25
|
+
valid_matching_key?(method, matching_key) &&
|
|
26
|
+
valid_bucketing_key?(method, key, bucketing_key) &&
|
|
27
|
+
valid_attributes?(method, attributes)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def valid_track_parameters(key, traffic_type_name, event_type, value, properties)
|
|
31
|
+
valid_track_key?(key) &&
|
|
32
|
+
valid_traffic_type_name?(traffic_type_name) &&
|
|
33
|
+
valid_event_type?(event_type) &&
|
|
34
|
+
valid_value?(value) &&
|
|
35
|
+
valid_properties?(properties)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def valid_split_parameters(split_name)
|
|
39
|
+
valid_split_name?(:split, split_name)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def valid_matcher_arguments(args)
|
|
43
|
+
return false if !args.key?(:attributes) && !args.key?(:value)
|
|
44
|
+
return false if args.key?(:value) && args[:value].nil?
|
|
45
|
+
return false if args.key?(:attributes) && args[:attributes].nil?
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def valid_flag_sets(method, flag_sets)
|
|
50
|
+
if flag_sets.nil? || !flag_sets.is_a?(Array)
|
|
51
|
+
@config.logger.error("#{method}: FlagSets must be a non-empty list.")
|
|
52
|
+
return []
|
|
53
|
+
end
|
|
54
|
+
if flag_sets.empty?
|
|
55
|
+
@config.logger.error("#{method}: FlagSets must be a non-empty list.")
|
|
56
|
+
return []
|
|
57
|
+
end
|
|
58
|
+
without_nil = Array.new
|
|
59
|
+
flag_sets.each { |flag_set|
|
|
60
|
+
if !flag_set.nil?
|
|
61
|
+
without_nil.push(flag_set)
|
|
62
|
+
next
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
log_nil("flag set", method)
|
|
66
|
+
}
|
|
67
|
+
if without_nil.length() == 0
|
|
68
|
+
log_invalid_flag_set_type(method)
|
|
69
|
+
return []
|
|
70
|
+
end
|
|
71
|
+
valid_flag_sets = Set[]
|
|
72
|
+
without_nil.compact.uniq.select do |flag_set|
|
|
73
|
+
if flag_set.nil? || !flag_set.is_a?(String)
|
|
74
|
+
log_invalid_flag_set_type(method)
|
|
75
|
+
elsif flag_set.is_a?(String) && flag_set.empty?
|
|
76
|
+
log_invalid_flag_set_type(method)
|
|
77
|
+
elsif !flag_set.empty? && string_match?(flag_set.strip.downcase, method, Flagset_regex, :log_invalid_match)
|
|
78
|
+
valid_flag_sets.add(flag_set.strip.downcase)
|
|
79
|
+
else
|
|
80
|
+
log_invalid_flag_set_type(method)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
!valid_flag_sets.empty? ? valid_flag_sets.to_a.sort : []
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def validate_fallback_treatment(method, fallback_treatment)
|
|
87
|
+
if !fallback_treatment.is_a? Engine::Models::FallbackTreatment
|
|
88
|
+
@config.logger.warn("#{method}: Fallback treatment instance should be FallbackTreatment, input is discarded")
|
|
89
|
+
return false
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if !fallback_treatment.treatment.is_a? String
|
|
93
|
+
@config.logger.warn("#{method}: Fallback treatment value should be str type, input is discarded")
|
|
94
|
+
return false
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
return false unless string_match?(fallback_treatment.treatment, method, Fallback_treatment_regex, :log_invalid_fallback_treatment)
|
|
98
|
+
|
|
99
|
+
if fallback_treatment.treatment.size > Fallback_treatment_size
|
|
100
|
+
@config.logger.warn("#{method}: Fallback treatment size should not exceed #{Fallback_treatment_size} characters")
|
|
101
|
+
return false
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
true
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def valid_split_name?(method, split_name)
|
|
108
|
+
if split_name.nil?
|
|
109
|
+
log_nil(:split_name, method)
|
|
110
|
+
return false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
unless string?(split_name)
|
|
114
|
+
log_invalid_type(:split_name, method)
|
|
115
|
+
return false
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
if empty_string?(split_name)
|
|
119
|
+
log_empty_string(:split_name, method)
|
|
120
|
+
return false
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
|
|
128
|
+
def string?(value)
|
|
129
|
+
value.is_a?(String) || value.is_a?(Symbol)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def empty_string?(value)
|
|
133
|
+
value.is_a?(String) && value.empty?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def number_or_string?(value)
|
|
137
|
+
(value.is_a?(Numeric) && !value.to_f.nan?) || string?(value)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def string_match?(value, method, regex_exp, log_if_invalid)
|
|
141
|
+
if regex_exp.match(value) == nil
|
|
142
|
+
method(log_if_invalid).call(value, method)
|
|
143
|
+
false
|
|
144
|
+
else
|
|
145
|
+
true
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def log_invalid_match(key, method)
|
|
150
|
+
@config.logger.error("#{method}: you passed #{key}, flag set must adhere to the regular expression #{Flagset_regex}. " +
|
|
151
|
+
"This means flag set must be alphanumeric, cannot be more than 50 characters long, and can only include a dash, underscore, " +
|
|
152
|
+
"period, or colon as separators of alphanumeric characters.")
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def log_nil(key, method)
|
|
156
|
+
msg_text = String.new("#{method}: you passed a nil #{key}, #{key} must be a non-empty String")
|
|
157
|
+
msg_text << " or a Symbol" if !key.equal?("flag set")
|
|
158
|
+
@config.logger.error(msg_text)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def log_empty_string(key, method)
|
|
162
|
+
@config.logger.error("#{method}: you passed an empty #{key}, #{key} must be a non-empty String or a Symbol")
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def log_invalid_type(key, method)
|
|
166
|
+
@config.logger.error("#{method}: you passed an invalid #{key} type, #{key} must be a non-empty String or a Symbol")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def log_invalid_flag_set_type(method)
|
|
170
|
+
@config.logger.warn("#{method}: you passed an invalid flag set type, flag set must be a non-empty String")
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def log_convert_numeric(key, method, value)
|
|
174
|
+
@config.logger.warn("#{method}: #{key} \"#{value}\" is not of type String, converting")
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def log_key_too_long(key, method)
|
|
178
|
+
@config.logger.error("#{method}: #{key} is too long - must be #{@config.max_key_size} characters or less")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def valid_key?(method, key)
|
|
182
|
+
if key.nil?
|
|
183
|
+
log_nil(:key, method)
|
|
184
|
+
return false
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
true
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def valid_matching_key?(method, matching_key)
|
|
191
|
+
if matching_key.nil?
|
|
192
|
+
log_nil(:matching_key, method)
|
|
193
|
+
return false
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
unless number_or_string?(matching_key)
|
|
197
|
+
log_invalid_type(:matching_key, method)
|
|
198
|
+
return false
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
if empty_string?(matching_key)
|
|
202
|
+
log_empty_string(:matching_key, method)
|
|
203
|
+
return false
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
log_convert_numeric(:matching_key, method, matching_key) if matching_key.is_a? Numeric
|
|
207
|
+
|
|
208
|
+
if matching_key.size > @config.max_key_size
|
|
209
|
+
log_key_too_long(:matching_key, method)
|
|
210
|
+
return false
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
true
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def valid_bucketing_key?(method, key, bucketing_key)
|
|
217
|
+
if key.is_a? Hash
|
|
218
|
+
if bucketing_key.nil?
|
|
219
|
+
log_nil(:bucketing_key, method)
|
|
220
|
+
return false
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
unless number_or_string?(bucketing_key)
|
|
224
|
+
log_invalid_type(:bucketing_key, method)
|
|
225
|
+
return false
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
if empty_string?(bucketing_key)
|
|
229
|
+
log_empty_string(:bucketing_key, method)
|
|
230
|
+
return false
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
log_convert_numeric(:bucketing_key, method, bucketing_key) if bucketing_key.is_a? Numeric
|
|
234
|
+
|
|
235
|
+
if bucketing_key.size > @config.max_key_size
|
|
236
|
+
log_key_too_long(:bucketing_key, method)
|
|
237
|
+
return false
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
true
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def valid_split_names?(method, split_names)
|
|
245
|
+
unless !split_names.nil? && split_names.is_a?(Array)
|
|
246
|
+
@config.logger.error("#{method}: feature_flag_names must be a non-empty Array")
|
|
247
|
+
return false
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
true
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def valid_attributes?(method, attributes)
|
|
254
|
+
unless attributes.nil? || attributes.is_a?(Hash)
|
|
255
|
+
@config.logger.error("#{method}: attributes must be of type Hash")
|
|
256
|
+
return false
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
true
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def valid_track_key?(key)
|
|
263
|
+
if key.nil?
|
|
264
|
+
log_nil(:key, :track)
|
|
265
|
+
return false
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
unless number_or_string?(key)
|
|
269
|
+
log_invalid_type(:key, :track)
|
|
270
|
+
return false
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
if empty_string?(key)
|
|
274
|
+
log_empty_string(:key, :track)
|
|
275
|
+
return false
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
log_convert_numeric(:key, :track, key) if key.is_a? Numeric
|
|
279
|
+
|
|
280
|
+
if key.size > @config.max_key_size
|
|
281
|
+
log_key_too_long(:key, :track)
|
|
282
|
+
return false
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
true
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def valid_event_type?(event_type)
|
|
289
|
+
if event_type.nil?
|
|
290
|
+
log_nil(:event_type, :track)
|
|
291
|
+
return false
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
unless string?(event_type)
|
|
295
|
+
log_invalid_type(:event_type, :track)
|
|
296
|
+
return false
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
if event_type.empty?
|
|
300
|
+
log_empty_string(:event_type, :track)
|
|
301
|
+
return false
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
if (event_type.to_s =~ /^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$/).nil?
|
|
305
|
+
@config.logger.error("track: you passed '#{event_type}', " \
|
|
306
|
+
'event_type must adhere to the regular expression ^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$. ' \
|
|
307
|
+
'This means an event name must be alphanumeric, cannot be more than 80 characters long, ' \
|
|
308
|
+
'and can only include a dash, underscore, period, or colon as separators of alphanumeric characters')
|
|
309
|
+
return false
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
true
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def valid_traffic_type_name?(traffic_type_name)
|
|
316
|
+
if traffic_type_name.nil?
|
|
317
|
+
log_nil(:traffic_type_name, :track)
|
|
318
|
+
return false
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
unless string?(traffic_type_name)
|
|
322
|
+
log_invalid_type(:traffic_type_name, :track)
|
|
323
|
+
return false
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
if traffic_type_name.empty?
|
|
327
|
+
log_empty_string(:traffic_type_name, :track)
|
|
328
|
+
return false
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
unless traffic_type_name == traffic_type_name.downcase
|
|
332
|
+
@config.logger.warn('track: traffic_type_name should be all lowercase - ' \
|
|
333
|
+
'converting string to lowercase')
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
true
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def valid_value?(value)
|
|
340
|
+
unless (value.is_a?(Numeric) && !value.to_f.nan?) || value.nil?
|
|
341
|
+
@config.logger.error('track: value must be Numeric')
|
|
342
|
+
return false
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
true
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def valid_properties?(properties)
|
|
349
|
+
unless properties.is_a?(Hash) || properties.nil?
|
|
350
|
+
@config.logger.error('track: properties must be a Hash')
|
|
351
|
+
return false
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
true
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def log_invalid_fallback_treatment(key, method)
|
|
358
|
+
@config.logger.warn("#{method}: Invalid treatment #{key}, Fallback treatment should match regex #{Fallback_treatment_regex}")
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
end
|