eppo-server-sdk 3.3.0 → 3.4.0

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.
data/README.md CHANGED
@@ -38,8 +38,40 @@ eppo_core = { path = '../eppo_core' }
38
38
 
39
39
  Make sure you remove the override before updating `Cargo.lock`. Otherwise, the lock file will be missing `eppo_core` checksum and will be unsuitable for release. (CI will warn you if you do this accidentally.)
40
40
 
41
+ ## Build locally
42
+
43
+ Install all dependencies:
44
+ ```sh
45
+ bundle install
46
+ ```
47
+
48
+ Build native extension:
49
+ ```sh
50
+ bundle exec rake build
51
+ ```
52
+
53
+ Run tests:
54
+ ```sh
55
+ bundle exec rspec
56
+ ```
57
+
41
58
  ## Releasing
42
59
 
43
60
  * Bump versions in `ruby-sdk/lib/eppo_client/version.rb` and `ruby-sdk/ext/eppo_client/Cargo.toml`
44
61
  * Run `cargo update --workspace --verbose` to update `Cargo.lock`
45
62
  * Run `bundle` to update `Gemfile.lock`
63
+
64
+
65
+ ## Building Ruby native lib
66
+
67
+ 1. Clone this repository at the desired Ruby SDK tag, eg.: `git clone --depth 1 --branch ruby-sdk@x.y.z https://github.com/Eppo-exp/eppo-multiplatform.git`
68
+ 2. Open `build.sh` and update `rb-sys-dock --platform <platform>` with the desired platform, eg.: `rb-sys-dock --platform x86_64-linux`
69
+ 3. Run `docker build --build-arg WORKDIR=$(pwd) -f Dockerfile.ruby.build -t ruby-sdk-builder .` to build the builder docker image
70
+ 4. Run the following command to build the gem with native lib:
71
+ ```
72
+ mkdir -p rust/cargo/registry && docker run --rm -it \
73
+ -v /var/run/docker.sock:/var/run/docker.sock \
74
+ -v /tmp:/tmp -v \
75
+ $(pwd)/rust:$(pwd)/rust ruby-sdk-builder
76
+ ```
77
+ 5. The gem will be available at `ruby-sdk/pkg/eppo-server-sdk-x.y.z-arch.gem`
@@ -1,18 +1,18 @@
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.3.0"
4
+ version = "3.4.0"
5
5
  edition = "2021"
6
6
  license = "MIT"
7
7
  publish = false
8
- rust-version = "1.71.1"
8
+ rust-version = "1.75.0"
9
9
 
10
10
  [lib]
11
11
  crate-type = ["cdylib"]
12
12
 
13
13
  [dependencies]
14
14
  env_logger = { version = "0.11.3", features = ["unstable-kv"] }
15
- eppo_core = { version = "4.1.1", features = ["vendored"] }
15
+ eppo_core = { version = "=7.0.0", features = ["vendored", "magnus"] }
16
16
  log = { version = "0.4.21", features = ["kv_serde"] }
17
17
  magnus = { version = "0.6.4" }
18
18
  serde = { version = "1.0.203", features = ["derive"] }
@@ -8,7 +8,7 @@ use eppo_core::{
8
8
  ufc::VariationType,
9
9
  Attributes, ContextAttributes,
10
10
  };
11
- use magnus::{error::Result, exception, prelude::*, Error, TryConvert, Value};
11
+ use magnus::{error::Result, exception, prelude::*, Error, IntoValue, Ruby, TryConvert, Value};
12
12
 
13
13
  use crate::{configuration::Configuration, SDK_METADATA};
14
14
 
@@ -116,7 +116,8 @@ impl Client {
116
116
  }
117
117
 
118
118
  pub fn get_assignment(
119
- &self,
119
+ ruby: &Ruby,
120
+ rb_self: &Self,
120
121
  flag_key: String,
121
122
  subject_key: String,
122
123
  subject_attributes: Value,
@@ -125,7 +126,7 @@ impl Client {
125
126
  let expected_type: VariationType = serde_magnus::deserialize(expected_type)?;
126
127
  let subject_attributes: Attributes = serde_magnus::deserialize(subject_attributes)?;
127
128
 
128
- let result = self
129
+ let result = rb_self
129
130
  .evaluator
130
131
  .get_assignment(
131
132
  &flag_key,
@@ -136,7 +137,7 @@ impl Client {
136
137
  // TODO: maybe expose possible errors individually.
137
138
  .map_err(|err| Error::new(exception::runtime_error(), err.to_string()))?;
138
139
 
139
- Ok(serde_magnus::serialize(&result).expect("assignment value should be serializable"))
140
+ Ok(result.into_value_with(&ruby))
140
141
  }
141
142
 
142
143
  pub fn get_assignment_details(
@@ -146,6 +147,8 @@ impl Client {
146
147
  subject_attributes: Value,
147
148
  expected_type: Value,
148
149
  ) -> Result<Value> {
150
+ let ruby = Ruby::get_with(subject_attributes);
151
+
149
152
  let expected_type: VariationType = serde_magnus::deserialize(expected_type)?;
150
153
  let subject_attributes: Attributes = serde_magnus::deserialize(subject_attributes)?;
151
154
 
@@ -156,7 +159,7 @@ impl Client {
156
159
  Some(expected_type),
157
160
  );
158
161
 
159
- Ok(serde_magnus::serialize(&result).expect("assignment value should be serializable"))
162
+ Ok(result.into_value_with(&ruby))
160
163
  }
161
164
 
162
165
  pub fn get_bandit_action(
@@ -173,7 +176,7 @@ impl Client {
173
176
  .map_err(|err| {
174
177
  Error::new(
175
178
  exception::runtime_error(),
176
- format!("enexpected value for subject_attributes: {err}"),
179
+ format!("Unexpected value for subject_attributes: {err}"),
177
180
  )
178
181
  })?;
179
182
  let actions = serde_magnus::deserialize(actions)?;
@@ -22,7 +22,7 @@ module EppoClient
22
22
  def init(config)
23
23
  config.validate
24
24
 
25
- if !@core.nil?
25
+ if @core
26
26
  STDERR.puts "Eppo Warning: multiple initialization of the client"
27
27
  @core.shutdown
28
28
  end
@@ -91,7 +91,10 @@ module EppoClient
91
91
  log_assignment(result[:assignment_event])
92
92
  log_bandit_action(result[:bandit_event])
93
93
 
94
- return {:variation => result[:variation], :action => result[:action]}
94
+ {
95
+ :variation => result[:variation],
96
+ :action => result[:action]
97
+ }
95
98
  end
96
99
 
97
100
  def get_bandit_action_details(flag_key, subject_key, subject_attributes, actions, default_variation)
@@ -102,7 +105,7 @@ module EppoClient
102
105
  log_assignment(result[:assignment_event])
103
106
  log_bandit_action(result[:bandit_event])
104
107
 
105
- return {
108
+ {
106
109
  :variation => result[:variation],
107
110
  :action => result[:action],
108
111
  :evaluationDetails => details
@@ -116,13 +119,11 @@ module EppoClient
116
119
  logger = Logger.new($stdout)
117
120
  begin
118
121
  assignment = @core.get_assignment(flag_key, subject_key, subject_attributes, expected_type)
119
- if not assignment then
120
- return default_value
121
- end
122
+ return default_value unless assignment
122
123
 
123
124
  log_assignment(assignment[:event])
124
125
 
125
- return assignment[:value][:value]
126
+ return assignment[:value]
126
127
  rescue StandardError => error
127
128
  logger.debug("[Eppo SDK] Failed to get assignment: #{error}")
128
129
 
@@ -137,19 +138,16 @@ module EppoClient
137
138
  result, event = @core.get_assignment_details(flag_key, subject_key, subject_attributes, expected_type)
138
139
  log_assignment(event)
139
140
 
140
- if not result[:variation] then
141
+ if !result[:variation]
141
142
  result[:variation] = default_value
142
- else
143
- # unwrap from AssignmentValue to untyped value
144
- result[:variation] = result[:variation][:value]
145
143
  end
146
144
 
147
- return result
145
+ result
148
146
  end
149
147
  # rubocop:enable Metrics/MethodLength
150
148
 
151
149
  def log_assignment(event)
152
- if not event then return end
150
+ return unless event
153
151
 
154
152
  # Because rust's AssignmentEvent has a #[flatten] extra_logging
155
153
  # field, serde_magnus serializes it as a normal HashMap with
@@ -170,7 +168,7 @@ module EppoClient
170
168
  end
171
169
 
172
170
  def log_bandit_action(event)
173
- if not event then return end
171
+ return unless event
174
172
 
175
173
  begin
176
174
  @assignment_logger.log_bandit_action(event)
@@ -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.3.0"
5
+ VERSION = "3.4.0"
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.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eppo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-22 00:00:00.000000000 Z
11
+ date: 2025-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys