eppo-server-sdk 3.1.2 → 3.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e157a64d8d72757a3bd049d7e40db5589fb7b16d6ff466ea4a1015dbb54fa066
4
- data.tar.gz: 9a4d5cd6edec77d1b8bf8103debe2b096816b6e9957a1c2308747a5182b5a703
3
+ metadata.gz: 58a6e5ef2e00c9c830661f2571eab4f6817e2ceaf40de3dd541b7f2421fb24c0
4
+ data.tar.gz: 8616534de1a08cd7c9d02570da27b15c64e4df0e2c805301bd3f4e54f1b6d3d0
5
5
  SHA512:
6
- metadata.gz: 1b98a6ee8aefd1b833f83ddae8141f42798f825a30f0a54d257f390aa24efc9d8e8a2f1c5b9ff1542db9c11700b7d5fac513c0fa1632aca2f5d22b1eb1a4a9b2
7
- data.tar.gz: abc686a5a7e46bf85ba655157de3b7ae9b9367e53603d962741d52edac3f42da1e24301a67145b6719663583a89083dbe0e5df757ebf0a6decc8a570f8f64edf
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.1.2"
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.0.0"
321
+ version = "4.1.0"
321
322
  source = "registry+https://github.com/rust-lang/crates.io-index"
322
- checksum = "b071fed21065318dcd6a91a443bd9f6b39796d727297b03d092e2e8dc9e02414"
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.100"
1035
+ version = "0.9.102"
1025
1036
  source = "registry+https://github.com/rust-lang/crates.io-index"
1026
- checksum = "87f2ba20be84b32fad6b0ce397764bcdd0f2dca4431cf7035f6a6721e5747565"
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.100"
1044
+ version = "0.9.102"
1034
1045
  source = "registry+https://github.com/rust-lang/crates.io-index"
1035
- checksum = "7ecae2bdcb118ee721d9a3929f89e8578237fade298dfcf8c928609aa88abc48"
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.124"
1309
+ version = "1.0.128"
1299
1310
  source = "registry+https://github.com/rust-lang/crates.io-index"
1300
- checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d"
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
@@ -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.1.2"
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.0.0" }
15
+ eppo_core = { version = "4.1.0", features = ["vendored"] }
16
16
  log = { version = "0.4.21", features = ["kv_serde"] }
17
- magnus = { version = "0.6.2" }
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, SdkMetadata,
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
- Ok(Config { api_key, base_url })
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 sdk_metadata = SdkMetadata {
45
- name: "ruby",
46
- version: env!("CARGO_PKG_VERSION"),
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(Some(poller_thread)),
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
+ }
@@ -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
  }
@@ -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
@@ -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
@@ -2,5 +2,5 @@
2
2
 
3
3
  # TODO: this version and ext/eppo_client/Cargo.toml should be in sync
4
4
  module EppoClient
5
- VERSION = "3.1.2"
5
+ VERSION = "3.2.2"
6
6
  end
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.1.2
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-08 00:00:00.000000000 Z
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