momento 0.4.9 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 616d2ff01199640c05162ca979fb1ab260c1522c8b86a46d34c68ade3f7c430b
4
- data.tar.gz: 54e756e639fd2c9fe5b5e004ccb0d1e6d9b6a9368ead7a8b4d518e908100b75a
3
+ metadata.gz: 8c0a2e256e81604bf29029b9b7e280ad7447a988b030e2b0e4597f1203ab1716
4
+ data.tar.gz: fcec32b5f2994ec2cd4c36a55b6e832d795347c9e4b7ce953b9ab364abbbc6d1
5
5
  SHA512:
6
- metadata.gz: 48f6a80d7798f86b4bcd0d90dc7cb2ba0bec542554e443c2453756cb31b61fbef3f2ff38ad0933b1a71207d45a7782882829247630616605f8dd6d3c5ad68a6d
7
- data.tar.gz: ab18d86ce358a2b63d67e953460dddb039c29d01412fddf730a4b55d3210910a1e43c759c78b375cf305c95e6d250f44259d0b6df7f34c1fead22ebbb4e727c7
6
+ metadata.gz: 4e41395f678e2b7cd093b26e0770d76883c4066479ab1beebb85ce6da66c78f0706965b6779d11a15838aa796f1bb73ba8d110b7527ba7ef6012ff6692f9568a
7
+ data.tar.gz: 907ecfb588f18ea17b34ac4d4e9539b451614f2ac0b14bed7500d2671f5cdf016981413d69473ac3cc09d173d2c46c1a924adcbcf21c92adb507629328880df0
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.4.9"
2
+ ".": "0.5.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,8 +1,22 @@
1
1
  # Changelog
2
2
 
3
- ## [0.4.9](https://github.com/momentohq/client-sdk-ruby/compare/momento/v0.4.8...momento/v0.4.9) (2024-04-30)
3
+ ## [0.5.0](https://github.com/momentohq/client-sdk-ruby/compare/momento/v0.4.9...momento/v0.5.0) (2024-06-18)
4
+
5
+
6
+ ### Features
7
+
8
+ * add InRegion pre-built config ([#180](https://github.com/momentohq/client-sdk-ruby/issues/180)) ([6dd2ef4](https://github.com/momentohq/client-sdk-ruby/commit/6dd2ef47443dbbd0cae28e1d4451c74352310aa3))
9
+ * add runtime version header, only send agent headers on first request ([#177](https://github.com/momentohq/client-sdk-ruby/issues/177)) ([2292a35](https://github.com/momentohq/client-sdk-ruby/commit/2292a3575c551a2a36c9c3f1a31f0c6870e1c4d1))
10
+ * add support for multiple grpc channels, fix configuration modifiers ([#176](https://github.com/momentohq/client-sdk-ruby/issues/176)) ([5753247](https://github.com/momentohq/client-sdk-ruby/commit/57532472d418db54c6eadd046ea6cbf0a53e4e96))
4
11
 
5
12
 
13
+ ### Bug Fixes
14
+
15
+ * add Gemfile.lock to .gitignore ([45e0b6c](https://github.com/momentohq/client-sdk-ruby/commit/45e0b6cdfb19a337f6cb6c17afe2f21fd86b1eb5))
16
+ * improve error handling for env var cred provider, other fixes ([#173](https://github.com/momentohq/client-sdk-ruby/issues/173)) ([c0b691b](https://github.com/momentohq/client-sdk-ruby/commit/c0b691b8c925d99b6a95a9cecee160b777b9dfab))
17
+
18
+ ## [0.4.9](https://github.com/momentohq/client-sdk-ruby/compare/momento/v0.4.8...momento/v0.4.9) (2024-04-30)
19
+
6
20
  ### Bug Fixes
7
21
 
8
22
  * remove token and specify email for the redundant tag ([#168](https://github.com/momentohq/client-sdk-ruby/issues/168)) ([c119376](https://github.com/momentohq/client-sdk-ruby/commit/c11937641acce6b55dbb7e59f87f548769ad9313))
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- momento (0.4.9)
4
+ momento (0.5.0)
5
5
  grpc (~> 1.62)
6
6
 
7
7
  GEM
@@ -54,7 +54,8 @@ GEM
54
54
  rainbow (3.1.1)
55
55
  rake (13.0.6)
56
56
  regexp_parser (2.6.0)
57
- rexml (3.2.5)
57
+ rexml (3.2.8)
58
+ strscan (>= 3.0.9)
58
59
  rspec (3.12.0)
59
60
  rspec-core (~> 3.12.0)
60
61
  rspec-expectations (~> 3.12.0)
@@ -94,12 +95,11 @@ GEM
94
95
  simplecov_json_formatter (~> 0.1)
95
96
  simplecov-html (0.12.3)
96
97
  simplecov_json_formatter (0.1.4)
98
+ strscan (3.1.0)
97
99
  tzinfo (2.0.5)
98
100
  concurrent-ruby (~> 1.0)
99
101
  unicode-display_width (2.3.0)
100
- webrick (1.7.0)
101
- yard (0.9.28)
102
- webrick (~> 1.7.0)
102
+ yard (0.9.36)
103
103
 
104
104
  PLATFORMS
105
105
  arm64-darwin-22
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <img src="https://docs.momentohq.com/img/momento-logo-forest.svg" alt="logo" width="400"/>
5
5
 
6
6
  [![project status](https://momentohq.github.io/standards-and-practices/badges/project-status-official.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)
7
- [![project stability](https://momentohq.github.io/standards-and-practices/badges/project-stability-beta.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)
7
+ [![project stability](https://momentohq.github.io/standards-and-practices/badges/project-stability-stable.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)
8
8
 
9
9
  # Momento Ruby Client Library
10
10
 
@@ -66,14 +66,24 @@ require 'momento'
66
66
  TTL_SECONDS = 12.5
67
67
 
68
68
  # The name of the cache to create *and delete*
69
- CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME')
69
+ CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME', 'ruby-examples')
70
70
 
71
71
  # Create a credential provider that loads a Momento API Key from an environment variable.
72
72
  credential_provider = Momento::CredentialProvider.from_env_var('MOMENTO_API_KEY')
73
73
 
74
+ # This is a reasonable configuration for dev work on a laptop.
75
+ configuration = Momento::Cache::Configurations::Laptop.latest
76
+ # This configuration might be better for a production where you want more aggressive timeouts
77
+ # configuration = Momento::Cache::Configuration::InRegion.latest
78
+ # To set a custom timeout, you can use the with_timeout method.
79
+ # configuration = configuration.with_timeout(10_000)
80
+ # To increase the number of TCP connections for a client where you expect a high volume of traffic,
81
+ # you can use the with_num_connections method.
82
+ # configuration = configuration.with_num_connections(4)
83
+
74
84
  # Instantiate a Momento client.
75
85
  client = Momento::CacheClient.new(
76
- configuration: Momento::Cache::Configurations::Laptop.latest,
86
+ configuration: configuration,
77
87
  credential_provider: credential_provider,
78
88
  default_ttl: TTL_SECONDS
79
89
  )
data/examples/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  test_copy.jpg
2
+ Gemfile.lock
data/examples/Gemfile CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem 'momento', '~> 0.2.0'
5
+ gem 'momento', '~> 0.4.9'
data/examples/README.md CHANGED
@@ -18,14 +18,13 @@ Then, set the required environment variables:
18
18
 
19
19
  ```bash
20
20
  export MOMENTO_API_KEY=<YOUR_API_KEY>
21
- export MOMENTO_CACHE_NAME=<YOUR_CACHE_NAME>
22
21
  ```
23
22
 
24
23
  And now you can run the example programs.
25
24
 
26
- * example.rb - shows off all the basic functionality
27
- * compact.rb - the same, written in a compact style
28
- * file.rb - demonstrates how to cache a file
25
+ * `ruby ./example.rb` - shows off all the basic functionality
26
+ * `ruby ./compact.rb` - the same, written in a compact style
27
+ * `ruby ./file.rb` - demonstrates how to cache a file
29
28
 
30
29
  If you wish to use the version of Momento in this repository, include the lib directory when you run the examples.
31
30
 
data/examples/compact.rb CHANGED
@@ -6,7 +6,7 @@ require 'momento'
6
6
  TTL_SECONDS = 10
7
7
 
8
8
  # The name of the cache to create *and delete*
9
- CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME')
9
+ CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME', 'ruby-examples')
10
10
 
11
11
  # Create a credential provider that loads a Momento API Key from an environment variable.
12
12
  credential_provider = Momento::CredentialProvider.from_env_var('MOMENTO_API_KEY')
data/examples/example.rb CHANGED
@@ -7,14 +7,24 @@ require 'momento'
7
7
  TTL_SECONDS = 12.5
8
8
 
9
9
  # The name of the cache to create *and delete*
10
- CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME')
10
+ CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME', 'ruby-examples')
11
11
 
12
12
  # Create a credential provider that loads a Momento API Key from an environment variable.
13
13
  credential_provider = Momento::CredentialProvider.from_env_var('MOMENTO_API_KEY')
14
14
 
15
+ # This is a reasonable configuration for dev work on a laptop.
16
+ configuration = Momento::Cache::Configurations::Laptop.latest
17
+ # This configuration might be better for a production where you want more aggressive timeouts
18
+ # configuration = Momento::Cache::Configuration::InRegion.latest
19
+ # To set a custom timeout, you can use the with_timeout method.
20
+ # configuration = configuration.with_timeout(10_000)
21
+ # To increase the number of TCP connections for a client where you expect a high volume of traffic,
22
+ # you can use the with_num_connections method.
23
+ # configuration = configuration.with_num_connections(4)
24
+
15
25
  # Instantiate a Momento client.
16
26
  client = Momento::CacheClient.new(
17
- configuration: Momento::Cache::Configurations::Laptop.latest,
27
+ configuration: configuration,
18
28
  credential_provider: credential_provider,
19
29
  default_ttl: TTL_SECONDS
20
30
  )
data/examples/file.rb CHANGED
@@ -9,7 +9,7 @@ require 'momento'
9
9
  TTL_SECONDS = 12.5
10
10
 
11
11
  # The name of the cache to create *and delete*
12
- CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME')
12
+ CACHE_NAME = ENV.fetch('MOMENTO_CACHE_NAME', 'ruby-examples')
13
13
 
14
14
  # So it can be run from the top of the repo
15
15
  # or from the examples directory.
@@ -67,6 +67,9 @@ module Momento
67
67
  @control_endpoint = credential_provider.control_endpoint
68
68
  @cache_endpoint = credential_provider.cache_endpoint
69
69
  @configuration = configuration
70
+ @next_cache_stub_index = 0
71
+ @num_cache_stubs = @configuration.transport_strategy.grpc_configuration.num_grpc_channels
72
+ @is_first_request = true
70
73
  end
71
74
 
72
75
  # Get a value in a cache.
@@ -95,7 +98,7 @@ module Momento
95
98
  builder.from_block do
96
99
  cache_stub.get(
97
100
  MomentoProtos::CacheClient::PB__GetRequest.new(cache_key: to_bytes(key)),
98
- metadata: { cache: validate_cache_name(cache_name) }
101
+ metadata: grpc_metadata(cache_name)
99
102
  )
100
103
  end
101
104
  end
@@ -129,7 +132,7 @@ module Momento
129
132
  ttl_milliseconds: ttl.milliseconds
130
133
  )
131
134
 
132
- cache_stub.set(req, metadata: { cache: validate_cache_name(cache_name) })
135
+ cache_stub.set(req, metadata: grpc_metadata(cache_name))
133
136
  end
134
137
  end
135
138
 
@@ -153,7 +156,7 @@ module Momento
153
156
  builder.from_block do
154
157
  cache_stub.delete(
155
158
  MomentoProtos::CacheClient::PB__DeleteRequest.new(cache_key: to_bytes(key)),
156
- metadata: { cache: validate_cache_name(cache_name) }
159
+ metadata: grpc_metadata(cache_name)
157
160
  )
158
161
  end
159
162
  end
@@ -254,7 +257,7 @@ module Momento
254
257
  )
255
258
 
256
259
  # noinspection RubyResolve
257
- cache_stub.sorted_set_put(req, metadata: { cache: validate_cache_name(cache_name) })
260
+ cache_stub.sorted_set_put(req, metadata: grpc_metadata(cache_name))
258
261
  end
259
262
  end
260
263
 
@@ -291,7 +294,7 @@ module Momento
291
294
  )
292
295
 
293
296
  # noinspection RubyResolve
294
- cache_stub.sorted_set_put(req, metadata: { cache: validate_cache_name(cache_name) })
297
+ cache_stub.sorted_set_put(req, metadata: grpc_metadata(cache_name))
295
298
  end
296
299
  end
297
300
 
@@ -331,7 +334,7 @@ module Momento
331
334
  )
332
335
 
333
336
  # noinspection RubyResolve
334
- cache_stub.sorted_set_fetch(req, metadata: { cache: validate_cache_name(cache_name) })
337
+ cache_stub.sorted_set_fetch(req, metadata: grpc_metadata(cache_name))
335
338
  end
336
339
  end
337
340
  # rubocop:enable Metrics/ParameterLists
@@ -339,9 +342,14 @@ module Momento
339
342
  private
340
343
 
341
344
  def cache_stub
342
- @cache_stub ||= CACHE_CLIENT_STUB_CLASS.new(@cache_endpoint, combined_credentials,
343
- timeout: @configuration.transport_strategy.grpc_configuration.deadline
344
- )
345
+ @cache_stubs ||= (1..@num_cache_stubs).map {
346
+ CACHE_CLIENT_STUB_CLASS.new(@cache_endpoint, combined_credentials,
347
+ timeout: @configuration.transport_strategy.grpc_configuration.deadline,
348
+ channel_args: { 'grpc.use_local_subchannel_pool' => 1 }
349
+ )
350
+ }
351
+ @next_cache_stub_index = (@next_cache_stub_index + 1) % @num_cache_stubs
352
+ @cache_stubs[@next_cache_stub_index]
345
353
  end
346
354
 
347
355
  def control_stub
@@ -355,7 +363,7 @@ module Momento
355
363
  def make_combined_credentials
356
364
  # :nocov:
357
365
  auth_proc = proc do
358
- { authorization: @api_key, agent: "ruby:#{VERSION}" }
366
+ { authorization: @api_key }
359
367
  end
360
368
  # :nocov:
361
369
 
@@ -439,6 +447,19 @@ module Momento
439
447
  end
440
448
  end
441
449
 
450
+ def grpc_metadata(cache_name)
451
+ if @is_first_request
452
+ @is_first_request = false
453
+ {
454
+ cache: validate_cache_name(cache_name),
455
+ Agent: "ruby:cache:#{VERSION}",
456
+ 'Runtime-Version': "ruby:#{RUBY_VERSION}"
457
+ }
458
+ else
459
+ { cache: validate_cache_name(cache_name) }
460
+ end
461
+ end
462
+
442
463
  # Return a UTF-8 version of the cache name.
443
464
  #
444
465
  # @param name [String] the cache name to validate
@@ -4,8 +4,34 @@ module Momento
4
4
  class Configuration
5
5
  attr_reader :transport_strategy
6
6
 
7
- def self.with_transport_strategy(transport_strategy)
8
- return Configuration.new(transport_strategy)
7
+ # Convenience function to set the client timeout in milliseconds. If the server has not responded within the
8
+ # specified time, the client will terminate the request with a DeadlineExceeded error.
9
+ def with_timeout(timeout_millis)
10
+ transport_strategy = @transport_strategy
11
+ grpc_config = transport_strategy.grpc_configuration
12
+ Configuration.new(
13
+ transport_strategy.with_grpc_configuration(
14
+ grpc_config.with_deadline(timeout_millis)
15
+ )
16
+ )
17
+ end
18
+
19
+ # Convenience function to set the number of TCP connections for the client. Each connection can multiplex up
20
+ # to 100 concurrent requests. The default is 1, and this should not be overridden unless you are making a high
21
+ # volume of requests. Can help distribute traffic more evenly for high-throughput use cases.
22
+ def with_num_connections(num_connections)
23
+ transport_strategy = @transport_strategy
24
+ grpc_config = transport_strategy.grpc_configuration
25
+ Configuration.new(
26
+ transport_strategy.with_grpc_configuration(
27
+ grpc_config.with_num_grpc_channels(num_connections)
28
+ )
29
+ )
30
+ end
31
+
32
+ # Copy constructor; creates a new Configuration with the specified transport strategy
33
+ def with_transport_strategy(transport_strategy)
34
+ Configuration.new(transport_strategy)
9
35
  end
10
36
 
11
37
  def initialize(transport_strategy)
@@ -12,6 +12,13 @@ module Momento
12
12
  return Configuration.new(StaticTransportStrategy.new(GrpcConfiguration.new(5000)))
13
13
  end
14
14
  end
15
+
16
+ # Default Laptop configuration with 1100ms client timeout
17
+ class InRegion < Cache::Configuration
18
+ def self.latest
19
+ return Configuration.new(StaticTransportStrategy.new(GrpcConfiguration.new(1100)))
20
+ end
21
+ end
15
22
  end
16
23
  end
17
24
  end
@@ -5,11 +5,20 @@ module Momento
5
5
  # complete before it is terminated with a DeadlineExceeded error
6
6
  attr_reader :deadline
7
7
 
8
- def self.with_deadline(deadline)
9
- return GrpcConfiguration.new(deadline)
8
+ # Number of gRPC channels to create. Each channel can multiplex up to
9
+ # 100 concurrent requests. The default is 1, and this should not be
10
+ # overridden unless you are making a high volume of requests.
11
+ attr_reader :num_grpc_channels
12
+
13
+ def with_deadline(deadline)
14
+ return GrpcConfiguration.new(deadline, @num_grpc_channels)
15
+ end
16
+
17
+ def with_num_grpc_channels(num_grpc_channels)
18
+ return GrpcConfiguration.new(@deadline, num_grpc_channels)
10
19
  end
11
20
 
12
- def initialize(deadline)
21
+ def initialize(deadline, num_grpc_channels = 1)
13
22
  unless deadline.is_a? Integer
14
23
  raise Momento::Error::InvalidArgumentError,
15
24
  'Client timeout must be an integer'
@@ -20,6 +29,7 @@ module Momento
20
29
  end
21
30
 
22
31
  @deadline = deadline
32
+ @num_grpc_channels = num_grpc_channels
23
33
  end
24
34
  end
25
35
  end
@@ -5,7 +5,7 @@ module Momento
5
5
  class StaticTransportStrategy < TransportStrategy
6
6
  attr_reader :grpc_configuration
7
7
 
8
- def self.with_grpc_configuration(grpc_configuration)
8
+ def with_grpc_configuration(grpc_configuration)
9
9
  return StaticTransportStrategy.new(grpc_configuration)
10
10
  end
11
11
  end
@@ -3,7 +3,7 @@ module Momento
3
3
  class TransportStrategy
4
4
  attr_reader :grpc_configuration
5
5
 
6
- def self.with_grpc_configuration(grpc_configuration)
6
+ def with_grpc_configuration(grpc_configuration)
7
7
  return TransportStrategy.new(grpc_configuration)
8
8
  end
9
9
 
@@ -126,11 +126,18 @@ module Momento
126
126
  class InvalidArgumentError < ArgumentError
127
127
  include Momento::Error
128
128
 
129
+ def initialize(details = "")
130
+ @details = details
131
+ super(message)
132
+ end
133
+
129
134
  # (see Momento::Error#error_code)
130
135
  def error_code
131
136
  :INVALID_ARGUMENT_ERROR
132
137
  end
133
138
 
139
+ attr_reader :details
140
+
134
141
  # (see Momento::Error#message)
135
142
  def message
136
143
  "Invalid argument passed to Momento client: #{details}"
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Momento
4
4
  # This gem's version.
5
- VERSION = "0.4.9"
5
+ VERSION = "0.5.0"
6
6
  end
@@ -1,6 +1,5 @@
1
1
  module Momento
2
2
  class CacheClient
3
-
4
3
  def sorted_set_fetch_by_score: (cache_name: String, sorted_set_name: String, min_score: Float | nil, max_score: Float | nil, sort_order: Symbol, offset: Integer, count: Integer) -> SortedSetFetchResponse
5
4
 
6
5
  def sorted_set_put_element: (cache_name: String, sorted_set_name: String, value: String, score: Float, collection_ttl: CollectionTtl) -> SortedSetPutElementResponse
@@ -1,7 +1,11 @@
1
1
  module Momento
2
2
  module Cache
3
3
  class Configuration
4
- def self.with_transport_strategy: -> Cache::Configuration
4
+ def with_timeout: -> Configuration
5
+
6
+ def with_num_connections: -> Configuration
7
+
8
+ def with_transport_strategy: -> Configuration
5
9
 
6
10
  attr_reader transport_strategy: TransportStrategy
7
11
  end
@@ -2,6 +2,8 @@ module Momento
2
2
  class GrpcConfiguration
3
3
  def self.with_deadline: -> GrpcConfiguration
4
4
 
5
+ def self.with_num_grpc_channels: -> GrpcConfiguration
6
+
5
7
  attr_reader deadline: Integer
6
8
  end
7
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: momento
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Momento
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-30 00:00:00.000000000 Z
11
+ date: 2024-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -321,7 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
321
321
  - !ruby/object:Gem::Version
322
322
  version: '0'
323
323
  requirements: []
324
- rubygems_version: 3.5.9
324
+ rubygems_version: 3.5.11
325
325
  signing_key:
326
326
  specification_version: 4
327
327
  summary: Client for Momento Serverless Cache