eppo-server-sdk 3.1.2 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Cargo.lock +20 -9
- data/Rakefile +2 -13
- data/build/x86-64_linux-setup.sh +17 -0
- data/ext/eppo_client/Cargo.toml +5 -4
- data/ext/eppo_client/src/client.rs +50 -20
- data/ext/eppo_client/src/configuration.rs +113 -0
- data/ext/eppo_client/src/gc_lock.rs +25 -0
- data/ext/eppo_client/src/lib.rs +21 -1
- data/lib/eppo_client/client.rb +8 -0
- data/lib/eppo_client/config.rb +4 -2
- data/lib/eppo_client/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58a6e5ef2e00c9c830661f2571eab4f6817e2ceaf40de3dd541b7f2421fb24c0
|
4
|
+
data.tar.gz: 8616534de1a08cd7c9d02570da27b15c64e4df0e2c805301bd3f4e54f1b6d3d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23fe167a77c13f00137469b6bf078cb27e907dc1a5b4d18cc6f9bcfbda0a60f9620425d92eca98f3a4d2034796cd5b7f09bf9d08f6a61e0c9fa66b14c5f3730b
|
7
|
+
data.tar.gz: 9722bfdd197f648bcfd82b9f93f232c834d8c17a43b73b221bcfe47927b2dc2ed81cf3a95ad856b6497479861f82093b7127e9bbaa814d39bca48c2fd6662977
|
data/Cargo.lock
CHANGED
@@ -304,7 +304,7 @@ dependencies = [
|
|
304
304
|
|
305
305
|
[[package]]
|
306
306
|
name = "eppo_client"
|
307
|
-
version = "3.
|
307
|
+
version = "3.2.2"
|
308
308
|
dependencies = [
|
309
309
|
"env_logger",
|
310
310
|
"eppo_core",
|
@@ -312,14 +312,15 @@ dependencies = [
|
|
312
312
|
"magnus",
|
313
313
|
"rb-sys",
|
314
314
|
"serde",
|
315
|
+
"serde_json",
|
315
316
|
"serde_magnus",
|
316
317
|
]
|
317
318
|
|
318
319
|
[[package]]
|
319
320
|
name = "eppo_core"
|
320
|
-
version = "4.
|
321
|
+
version = "4.1.0"
|
321
322
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
322
|
-
checksum = "
|
323
|
+
checksum = "626df025f5b474b42ead14953310e31e81e4b88ce52a993573bf87bc9def12d4"
|
323
324
|
dependencies = [
|
324
325
|
"chrono",
|
325
326
|
"derive_more",
|
@@ -906,6 +907,15 @@ version = "0.1.5"
|
|
906
907
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
907
908
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
908
909
|
|
910
|
+
[[package]]
|
911
|
+
name = "openssl-src"
|
912
|
+
version = "300.3.1+3.3.1"
|
913
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
914
|
+
checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91"
|
915
|
+
dependencies = [
|
916
|
+
"cc",
|
917
|
+
]
|
918
|
+
|
909
919
|
[[package]]
|
910
920
|
name = "openssl-sys"
|
911
921
|
version = "0.9.103"
|
@@ -914,6 +924,7 @@ checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
|
|
914
924
|
dependencies = [
|
915
925
|
"cc",
|
916
926
|
"libc",
|
927
|
+
"openssl-src",
|
917
928
|
"pkg-config",
|
918
929
|
"vcpkg",
|
919
930
|
]
|
@@ -1021,18 +1032,18 @@ dependencies = [
|
|
1021
1032
|
|
1022
1033
|
[[package]]
|
1023
1034
|
name = "rb-sys"
|
1024
|
-
version = "0.9.
|
1035
|
+
version = "0.9.102"
|
1025
1036
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1026
|
-
checksum = "
|
1037
|
+
checksum = "df4dec4b1d304c3b308a2cd86b1216ea45dd4361f4e9fa056f108332d0a450c1"
|
1027
1038
|
dependencies = [
|
1028
1039
|
"rb-sys-build",
|
1029
1040
|
]
|
1030
1041
|
|
1031
1042
|
[[package]]
|
1032
1043
|
name = "rb-sys-build"
|
1033
|
-
version = "0.9.
|
1044
|
+
version = "0.9.102"
|
1034
1045
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1035
|
-
checksum = "
|
1046
|
+
checksum = "1d71de3e29d174b8fb17b5d4470f27d7aa2605f8a9d05fda0d3aeff30e05a570"
|
1036
1047
|
dependencies = [
|
1037
1048
|
"bindgen",
|
1038
1049
|
"lazy_static",
|
@@ -1295,9 +1306,9 @@ dependencies = [
|
|
1295
1306
|
|
1296
1307
|
[[package]]
|
1297
1308
|
name = "serde_json"
|
1298
|
-
version = "1.0.
|
1309
|
+
version = "1.0.128"
|
1299
1310
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1300
|
-
checksum = "
|
1311
|
+
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
1301
1312
|
dependencies = [
|
1302
1313
|
"itoa",
|
1303
1314
|
"memchr",
|
data/Rakefile
CHANGED
@@ -1,18 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
|
-
require "rspec/core/rake_task"
|
5
4
|
require_relative 'lib/eppo_client/version'
|
6
5
|
|
7
6
|
GEM_NAME = 'eppo-server-sdk'
|
8
7
|
GEM_VERSION = EppoClient::VERSION
|
9
8
|
|
10
|
-
RSpec::Core::RakeTask.new(:spec)
|
11
|
-
|
12
|
-
require "rubocop/rake_task"
|
13
|
-
|
14
|
-
RuboCop::RakeTask.new
|
15
|
-
|
16
9
|
require "rb_sys/extensiontask"
|
17
10
|
|
18
11
|
task default: :build
|
@@ -21,6 +14,8 @@ GEMSPEC = Gem::Specification.load("eppo-server-sdk.gemspec")
|
|
21
14
|
|
22
15
|
RbSys::ExtensionTask.new("eppo_client", GEMSPEC) do |ext|
|
23
16
|
ext.lib_dir = "lib/eppo_client"
|
17
|
+
|
18
|
+
ext.cross_compile = true
|
24
19
|
end
|
25
20
|
|
26
21
|
task build: :compile do
|
@@ -43,11 +38,5 @@ task :clean do
|
|
43
38
|
system 'rm *.gem'
|
44
39
|
end
|
45
40
|
|
46
|
-
RSpec::Core::RakeTask.new(:test) do |task|
|
47
|
-
root_dir = Rake.application.original_dir
|
48
|
-
task.pattern = "#{root_dir}/spec/*_spec.rb"
|
49
|
-
task.verbose = false
|
50
|
-
end
|
51
|
-
|
52
41
|
task test: :devinstall
|
53
42
|
task test_refreshed_data: [:devinstall, 'test-data']
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
## From:
|
4
|
+
## https://github.com/BoundaryML/baml/blob/canary/engine/language_client_ruby/x86-64_linux-setup.sh
|
5
|
+
##
|
6
|
+
|
7
|
+
set -euxo pipefail
|
8
|
+
|
9
|
+
# from https://serverfault.com/questions/1161816/mirrorlist-centos-org-no-longer-resolve
|
10
|
+
sudo sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo
|
11
|
+
sudo sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo
|
12
|
+
sudo sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
|
13
|
+
|
14
|
+
ls /etc/yum.repos.d/
|
15
|
+
|
16
|
+
# We need this to build engine/, since it's needed for OpenSSL
|
17
|
+
sudo yum install -y perl-IPC-Cmd
|
data/ext/eppo_client/Cargo.toml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
[package]
|
2
2
|
name = "eppo_client"
|
3
3
|
# TODO: this version and lib/eppo_client/version.rb should be in sync
|
4
|
-
version = "3.
|
4
|
+
version = "3.2.2"
|
5
5
|
edition = "2021"
|
6
6
|
license = "MIT"
|
7
7
|
publish = false
|
@@ -12,9 +12,10 @@ crate-type = ["cdylib"]
|
|
12
12
|
|
13
13
|
[dependencies]
|
14
14
|
env_logger = { version = "0.11.3", features = ["unstable-kv"] }
|
15
|
-
eppo_core = { version = "4.
|
15
|
+
eppo_core = { version = "4.1.0", features = ["vendored"] }
|
16
16
|
log = { version = "0.4.21", features = ["kv_serde"] }
|
17
|
-
magnus = { version = "0.6.
|
17
|
+
magnus = { version = "0.6.4" }
|
18
18
|
serde = { version = "1.0.203", features = ["derive"] }
|
19
19
|
serde_magnus = "0.8.1"
|
20
|
-
rb-sys = "0.9"
|
20
|
+
rb-sys = "0.9.102"
|
21
|
+
serde_json = "1.0.128"
|
@@ -1,20 +1,24 @@
|
|
1
|
-
use std::{cell::RefCell, sync::Arc};
|
1
|
+
use std::{cell::RefCell, sync::Arc, time::Duration};
|
2
2
|
|
3
3
|
use eppo_core::{
|
4
4
|
configuration_fetcher::{ConfigurationFetcher, ConfigurationFetcherConfig},
|
5
5
|
configuration_store::ConfigurationStore,
|
6
6
|
eval::{Evaluator, EvaluatorConfig},
|
7
|
-
poller_thread::PollerThread,
|
7
|
+
poller_thread::{PollerThread, PollerThreadConfig},
|
8
8
|
ufc::VariationType,
|
9
|
-
Attributes, ContextAttributes,
|
9
|
+
Attributes, ContextAttributes,
|
10
10
|
};
|
11
11
|
use magnus::{error::Result, exception, prelude::*, Error, TryConvert, Value};
|
12
12
|
|
13
|
+
use crate::{configuration::Configuration, SDK_METADATA};
|
14
|
+
|
13
15
|
#[derive(Debug)]
|
14
16
|
#[magnus::wrap(class = "EppoClient::Core::Config", size, free_immediately)]
|
15
17
|
pub struct Config {
|
16
18
|
api_key: String,
|
17
19
|
base_url: String,
|
20
|
+
poll_interval: Option<Duration>,
|
21
|
+
poll_jitter: Duration,
|
18
22
|
}
|
19
23
|
|
20
24
|
impl TryConvert for Config {
|
@@ -22,12 +26,21 @@ impl TryConvert for Config {
|
|
22
26
|
fn try_convert(val: magnus::Value) -> Result<Self> {
|
23
27
|
let api_key = String::try_convert(val.funcall("api_key", ())?)?;
|
24
28
|
let base_url = String::try_convert(val.funcall("base_url", ())?)?;
|
25
|
-
|
29
|
+
let poll_interval_seconds =
|
30
|
+
Option::<u64>::try_convert(val.funcall("poll_interval_seconds", ())?)?;
|
31
|
+
let poll_jitter_seconds = u64::try_convert(val.funcall("poll_jitter_seconds", ())?)?;
|
32
|
+
Ok(Config {
|
33
|
+
api_key,
|
34
|
+
base_url,
|
35
|
+
poll_interval: poll_interval_seconds.map(Duration::from_secs),
|
36
|
+
poll_jitter: Duration::from_secs(poll_jitter_seconds),
|
37
|
+
})
|
26
38
|
}
|
27
39
|
}
|
28
40
|
|
29
41
|
#[magnus::wrap(class = "EppoClient::Core::Client")]
|
30
42
|
pub struct Client {
|
43
|
+
configuration_store: Arc<ConfigurationStore>,
|
31
44
|
evaluator: Evaluator,
|
32
45
|
// Magnus only allows sharing aliased references (&T) through the API, so we need to use RefCell
|
33
46
|
// to get interior mutability.
|
@@ -41,29 +54,35 @@ impl Client {
|
|
41
54
|
pub fn new(config: Config) -> Client {
|
42
55
|
let configuration_store = Arc::new(ConfigurationStore::new());
|
43
56
|
|
44
|
-
let
|
45
|
-
|
46
|
-
|
57
|
+
let poller_thread = if let Some(poll_interval) = config.poll_interval {
|
58
|
+
Some(
|
59
|
+
PollerThread::start_with_config(
|
60
|
+
ConfigurationFetcher::new(ConfigurationFetcherConfig {
|
61
|
+
base_url: config.base_url,
|
62
|
+
api_key: config.api_key,
|
63
|
+
sdk_metadata: SDK_METADATA,
|
64
|
+
}),
|
65
|
+
configuration_store.clone(),
|
66
|
+
PollerThreadConfig {
|
67
|
+
interval: poll_interval,
|
68
|
+
jitter: config.poll_jitter,
|
69
|
+
},
|
70
|
+
)
|
71
|
+
.expect("should be able to start poller thread"),
|
72
|
+
)
|
73
|
+
} else {
|
74
|
+
None
|
47
75
|
};
|
48
76
|
|
49
|
-
let poller_thread = PollerThread::start(
|
50
|
-
ConfigurationFetcher::new(ConfigurationFetcherConfig {
|
51
|
-
base_url: config.base_url,
|
52
|
-
api_key: config.api_key,
|
53
|
-
sdk_metadata: sdk_metadata.clone(),
|
54
|
-
}),
|
55
|
-
configuration_store.clone(),
|
56
|
-
)
|
57
|
-
.expect("should be able to start poller thread");
|
58
|
-
|
59
77
|
let evaluator = Evaluator::new(EvaluatorConfig {
|
60
|
-
configuration_store,
|
61
|
-
sdk_metadata,
|
78
|
+
configuration_store: configuration_store.clone(),
|
79
|
+
sdk_metadata: SDK_METADATA,
|
62
80
|
});
|
63
81
|
|
64
82
|
Client {
|
83
|
+
configuration_store,
|
65
84
|
evaluator,
|
66
|
-
poller_thread: RefCell::new(
|
85
|
+
poller_thread: RefCell::new(poller_thread),
|
67
86
|
}
|
68
87
|
}
|
69
88
|
|
@@ -171,6 +190,17 @@ impl Client {
|
|
171
190
|
serde_magnus::serialize(&result)
|
172
191
|
}
|
173
192
|
|
193
|
+
pub fn get_configuration(&self) -> Option<Configuration> {
|
194
|
+
self.configuration_store
|
195
|
+
.get_configuration()
|
196
|
+
.map(|it| it.into())
|
197
|
+
}
|
198
|
+
|
199
|
+
pub fn set_configuration(&self, configuration: &Configuration) {
|
200
|
+
self.configuration_store
|
201
|
+
.set_configuration(configuration.clone().into())
|
202
|
+
}
|
203
|
+
|
174
204
|
pub fn shutdown(&self) {
|
175
205
|
if let Some(t) = self.poller_thread.take() {
|
176
206
|
let _ = t.shutdown();
|
@@ -0,0 +1,113 @@
|
|
1
|
+
use std::sync::Arc;
|
2
|
+
|
3
|
+
use magnus::{function, method, prelude::*, scan_args::get_kwargs, Error, RHash, RString, Ruby};
|
4
|
+
|
5
|
+
use eppo_core::{ufc::UniversalFlagConfig, Configuration as CoreConfiguration};
|
6
|
+
|
7
|
+
use crate::{gc_lock::GcLock, SDK_METADATA};
|
8
|
+
|
9
|
+
pub(crate) fn init(ruby: &Ruby) -> Result<(), Error> {
|
10
|
+
let eppo_client = ruby.define_module("EppoClient")?;
|
11
|
+
|
12
|
+
let configuration = eppo_client.define_class("Configuration", magnus::class::object())?;
|
13
|
+
configuration.define_singleton_method("new", function!(Configuration::new, 1))?;
|
14
|
+
configuration.define_method(
|
15
|
+
"flags_configuration",
|
16
|
+
method!(Configuration::flags_configuration, 0),
|
17
|
+
)?;
|
18
|
+
configuration.define_method(
|
19
|
+
"bandits_configuration",
|
20
|
+
method!(Configuration::bandits_configuration, 0),
|
21
|
+
)?;
|
22
|
+
|
23
|
+
Ok(())
|
24
|
+
}
|
25
|
+
|
26
|
+
#[derive(Debug, Clone)]
|
27
|
+
#[magnus::wrap(class = "EppoClient::Configuration", free_immediately)]
|
28
|
+
pub struct Configuration {
|
29
|
+
inner: Arc<CoreConfiguration>,
|
30
|
+
}
|
31
|
+
|
32
|
+
impl Configuration {
|
33
|
+
fn new(ruby: &Ruby, kw: RHash) -> Result<Configuration, Error> {
|
34
|
+
let args = get_kwargs(kw, &["flags_configuration"], &["bandits_configuration"])?;
|
35
|
+
let (flags_configuration,): (RString,) = args.required;
|
36
|
+
let (bandits_configuration,): (Option<Option<RString>>,) = args.optional;
|
37
|
+
let rest: RHash = args.splat;
|
38
|
+
if !rest.is_empty() {
|
39
|
+
return Err(Error::new(
|
40
|
+
ruby.exception_arg_error(),
|
41
|
+
format!("unexpected keyword arguments: {:?}", rest),
|
42
|
+
));
|
43
|
+
}
|
44
|
+
|
45
|
+
let inner = {
|
46
|
+
let _gc_lock = GcLock::new(ruby);
|
47
|
+
|
48
|
+
Arc::new(CoreConfiguration::from_server_response(
|
49
|
+
UniversalFlagConfig::from_json(
|
50
|
+
SDK_METADATA,
|
51
|
+
unsafe {
|
52
|
+
// SAFETY: we have disabled GC, so the memory can't be modified concurrently.
|
53
|
+
flags_configuration.as_slice()
|
54
|
+
}
|
55
|
+
.to_vec(),
|
56
|
+
)
|
57
|
+
.map_err(|err| {
|
58
|
+
Error::new(
|
59
|
+
ruby.exception_arg_error(),
|
60
|
+
format!("failed to parse flags_configuration: {err:?}"),
|
61
|
+
)
|
62
|
+
})?,
|
63
|
+
bandits_configuration
|
64
|
+
.flatten()
|
65
|
+
.map(|bandits| {
|
66
|
+
serde_json::from_slice(unsafe {
|
67
|
+
// SAFETY: we have disabled GC, so the memory can't be modified concurrently.
|
68
|
+
bandits.as_slice()
|
69
|
+
})
|
70
|
+
})
|
71
|
+
.transpose()
|
72
|
+
.map_err(|err| {
|
73
|
+
Error::new(
|
74
|
+
ruby.exception_arg_error(),
|
75
|
+
format!("failed to parse bandits_configuration: {err:?}"),
|
76
|
+
)
|
77
|
+
})?,
|
78
|
+
))
|
79
|
+
};
|
80
|
+
|
81
|
+
Ok(Configuration { inner })
|
82
|
+
}
|
83
|
+
|
84
|
+
fn flags_configuration(ruby: &Ruby, rb_self: &Self) -> Result<RString, Error> {
|
85
|
+
Ok(ruby.str_from_slice(rb_self.inner.flags.to_json()))
|
86
|
+
}
|
87
|
+
|
88
|
+
fn bandits_configuration(ruby: &Ruby, rb_self: &Self) -> Result<Option<RString>, Error> {
|
89
|
+
let Some(bandits) = &rb_self.inner.bandits else {
|
90
|
+
return Ok(None)
|
91
|
+
};
|
92
|
+
let vec = serde_json::to_vec(bandits).map_err(|err| {
|
93
|
+
// this should never happen
|
94
|
+
Error::new(
|
95
|
+
ruby.exception_runtime_error(),
|
96
|
+
format!("failed to serialize bandits configuration: {err:?}"),
|
97
|
+
)
|
98
|
+
})?;
|
99
|
+
Ok(Some(ruby.str_from_slice(&vec)))
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
impl From<Arc<CoreConfiguration>> for Configuration {
|
104
|
+
fn from(inner: Arc<CoreConfiguration>) -> Configuration {
|
105
|
+
Configuration { inner }
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
impl From<Configuration> for Arc<CoreConfiguration> {
|
110
|
+
fn from(value: Configuration) -> Arc<CoreConfiguration> {
|
111
|
+
value.inner
|
112
|
+
}
|
113
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
use magnus::Ruby;
|
2
|
+
|
3
|
+
pub struct GcLock<'a> {
|
4
|
+
ruby: &'a Ruby,
|
5
|
+
/// Holds `true` if GC was already disabled before acquiring the lock (so it doesn't need to be
|
6
|
+
/// re-enabled).
|
7
|
+
gc_was_disabled: bool,
|
8
|
+
}
|
9
|
+
|
10
|
+
impl<'a> GcLock<'a> {
|
11
|
+
pub fn new(ruby: &'a Ruby) -> GcLock<'a> {
|
12
|
+
GcLock {
|
13
|
+
ruby,
|
14
|
+
gc_was_disabled: ruby.gc_disable(),
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
impl<'a> Drop for GcLock<'a> {
|
20
|
+
fn drop(&mut self) {
|
21
|
+
if !self.gc_was_disabled {
|
22
|
+
self.ruby.gc_enable();
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
data/ext/eppo_client/src/lib.rs
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
mod client;
|
2
|
+
mod configuration;
|
3
|
+
mod gc_lock;
|
2
4
|
|
5
|
+
use eppo_core::SdkMetadata;
|
3
6
|
use magnus::{function, method, prelude::*, Error, Object, Ruby};
|
4
7
|
|
5
8
|
use crate::client::Client;
|
6
9
|
|
10
|
+
pub(crate) const SDK_METADATA: SdkMetadata = SdkMetadata {
|
11
|
+
name: "ruby",
|
12
|
+
version: env!("CARGO_PKG_VERSION"),
|
13
|
+
};
|
14
|
+
|
7
15
|
#[magnus::init]
|
8
16
|
fn init(ruby: &Ruby) -> Result<(), Error> {
|
9
|
-
env_logger::Builder::from_env(env_logger::Env::new().default_filter_or("eppo")).init();
|
17
|
+
env_logger::Builder::from_env(env_logger::Env::new().default_filter_or("eppo=debug")).init();
|
10
18
|
|
11
19
|
let eppo_client = ruby.define_module("EppoClient")?;
|
12
20
|
let core = eppo_client.define_module("Core")?;
|
@@ -23,12 +31,24 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
23
31
|
"get_bandit_action_details",
|
24
32
|
method!(Client::get_bandit_action_details, 5),
|
25
33
|
)?;
|
34
|
+
core_client.define_method("configuration", method!(Client::get_configuration, 0))?;
|
35
|
+
core_client.define_method("configuration=", method!(Client::set_configuration, 1))?;
|
26
36
|
core_client.define_method("shutdown", method!(Client::shutdown, 0))?;
|
27
37
|
|
28
38
|
core.const_set(
|
29
39
|
"DEFAULT_BASE_URL",
|
30
40
|
eppo_core::configuration_fetcher::DEFAULT_BASE_URL,
|
31
41
|
)?;
|
42
|
+
core.const_set(
|
43
|
+
"DEFAULT_POLL_INTERVAL_SECONDS",
|
44
|
+
eppo_core::poller_thread::PollerThreadConfig::DEFAULT_POLL_INTERVAL.as_secs(),
|
45
|
+
)?;
|
46
|
+
core.const_set(
|
47
|
+
"DEFAULT_POLL_JITTER_SECONDS",
|
48
|
+
eppo_core::poller_thread::PollerThreadConfig::DEFAULT_POLL_JITTER.as_secs(),
|
49
|
+
)?;
|
50
|
+
|
51
|
+
configuration::init(ruby)?;
|
32
52
|
|
33
53
|
Ok(())
|
34
54
|
}
|
data/lib/eppo_client/client.rb
CHANGED
@@ -24,6 +24,14 @@ module EppoClient
|
|
24
24
|
@core = EppoClient::Core::Client.new(config)
|
25
25
|
end
|
26
26
|
|
27
|
+
def configuration
|
28
|
+
@core.configuration
|
29
|
+
end
|
30
|
+
|
31
|
+
def configuration=(configuration)
|
32
|
+
@core.configuration = configuration
|
33
|
+
end
|
34
|
+
|
27
35
|
def shutdown
|
28
36
|
@core.shutdown
|
29
37
|
end
|
data/lib/eppo_client/config.rb
CHANGED
@@ -6,12 +6,14 @@ require_relative "assignment_logger"
|
|
6
6
|
module EppoClient
|
7
7
|
# The class for configuring the Eppo client singleton
|
8
8
|
class Config
|
9
|
-
attr_reader :api_key, :assignment_logger, :base_url
|
9
|
+
attr_reader :api_key, :assignment_logger, :base_url, :poll_interval_seconds, :poll_jitter_seconds
|
10
10
|
|
11
|
-
def initialize(api_key, assignment_logger: AssignmentLogger.new, base_url: EppoClient::Core::DEFAULT_BASE_URL)
|
11
|
+
def initialize(api_key, assignment_logger: AssignmentLogger.new, base_url: EppoClient::Core::DEFAULT_BASE_URL, poll_interval_seconds: EppoClient::Core::DEFAULT_POLL_INTERVAL_SECONDS, poll_jitter_seconds: EppoClient::Core::DEFAULT_POLL_JITTER_SECONDS, initial_configuration: nil)
|
12
12
|
@api_key = api_key
|
13
13
|
@assignment_logger = assignment_logger
|
14
14
|
@base_url = base_url
|
15
|
+
@poll_interval_seconds = poll_interval_seconds
|
16
|
+
@poll_jitter_seconds = poll_jitter_seconds
|
15
17
|
end
|
16
18
|
|
17
19
|
def validate
|
data/lib/eppo_client/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eppo-server-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eppo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -27,10 +27,13 @@ files:
|
|
27
27
|
- README.md
|
28
28
|
- Rakefile
|
29
29
|
- Steepfile
|
30
|
+
- build/x86-64_linux-setup.sh
|
30
31
|
- ext/eppo_client/Cargo.toml
|
31
32
|
- ext/eppo_client/build.rs
|
32
33
|
- ext/eppo_client/extconf.rb
|
33
34
|
- ext/eppo_client/src/client.rs
|
35
|
+
- ext/eppo_client/src/configuration.rs
|
36
|
+
- ext/eppo_client/src/gc_lock.rs
|
34
37
|
- ext/eppo_client/src/lib.rs
|
35
38
|
- lib/eppo_client.rb
|
36
39
|
- lib/eppo_client/assignment_logger.rb
|