rails-brotli-cache 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38153c74bf09ef2a13760b3dea18a3a3e97790104b1af8a8d244ee104d0ad34e
4
- data.tar.gz: ed7760dd1e7373fa7e855f57ec7082a185f68b114e43bd051d29fb4be7619020
3
+ metadata.gz: e109b9b356474fb8085b1cceaa892695de997465db4c90872556f76419da8f86
4
+ data.tar.gz: c8422310e9fed160052637a40dc7b1150b938c0f891b3b7b011eacdd11b8e4bb
5
5
  SHA512:
6
- metadata.gz: dc9430106e033158f55f6421d42253a8aaec9b62833687538a289010e8b67b1ffc4a75ba0b71071e5925b7256d2d070b5930719ebd40d5a60f28dc6d7cd4cd19
7
- data.tar.gz: 47483feabfac21321eb6e4e6a0df6d5ffa8646261dbeb7b728897f3026f4deff699e682a4cf525f8cca79b824082173637baf9517d8e96c3cfd91aaf9b0b3291
6
+ metadata.gz: 6b435443fbf3a6a09baed87b124429e43dcd4d3fbd06cab175a15818b397285aeab96ad0694dc8a2f0e0d91c3478400ba0e3081045e93ca63e275e62626f0e0d
7
+ data.tar.gz: 95af20d56721fbe1e9118b29a0fa1f7dc3fe5825d8c7ee04d77b783b96b405d6b1e765f4d8b63e8668d9414ca1e716cc010e3201d7a93340d35251ebd966f9e8
data/README.md CHANGED
@@ -9,7 +9,7 @@ You can check out [this blog post](https://pawelurbanek.com/rails-brotli-cache)
9
9
  `Gemfile`
10
10
 
11
11
  ```ruby
12
- gem 'brotli' # brotli is an optional dependency because other compressors are supported
12
+ gem 'brotli' # an optional dependency, other compressors are supported
13
13
  gem 'rails-brotli-cache'
14
14
  ```
15
15
 
@@ -139,10 +139,21 @@ config.cache_store = RailsBrotliCache::Store.new(
139
139
  ```
140
140
 
141
141
  ```ruby
142
+
143
+ class ZSTDCompressor
144
+ def self.deflate(payload)
145
+ ::Zstd.compress(payload, 10)
146
+ end
147
+
148
+ def self.inflate(payload)
149
+ ::Zstd.decompress(payload)
150
+ end
151
+ end
152
+
142
153
  Rails.cache.write('test-key', json, compressor_class: Snappy)
143
154
  ```
144
155
 
145
- This config expects a class which defines two class methods `inflate` and `deflate`. It allows you to instead use for example a [Google Snappy algorithm](https://github.com/miyucy/snappy) offering even better performance for the cost of worse compresion ratios. Optionally, you can define a custom class wrapping any compression library.
156
+ This config expects a class that defines two methods, `inflate` and `deflate`. It allows to use, for example, a [ZSTD by Facebook](https://github.com/SpringMT/zstd-ruby), offering even better performance and compression.
146
157
 
147
158
  ## Testing
148
159
 
data/benchmarks/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'brotli'
3
4
  gem 'rails-brotli-cache', path: "../"
4
5
  gem 'redis'
5
6
  gem 'dalli'
7
+ gem 'zstd-ruby'
data/benchmarks/main.rb CHANGED
@@ -1,31 +1,62 @@
1
1
  require 'active_support'
2
2
  require 'active_support/core_ext/hash'
3
3
  require 'net/http'
4
+ require 'brotli'
4
5
  require 'rails-brotli-cache'
5
6
  require 'benchmark'
7
+ require 'zstd-ruby'
8
+
9
+ class ZSTDCompressor
10
+ def self.deflate(payload)
11
+ ::Zstd.compress(payload, 10)
12
+ end
13
+
14
+ def self.inflate(payload)
15
+ ::Zstd.decompress(payload)
16
+ end
17
+ end
6
18
 
7
19
  memory_cache = ActiveSupport::Cache::MemoryStore.new(compress: true) # memory store does not use compression by default
8
20
  brotli_memory_cache = RailsBrotliCache::Store.new(memory_cache)
21
+ zstd_memory_cache = RailsBrotliCache::Store.new(memory_cache, compressor_class: ZSTDCompressor, prefix: "zs-")
22
+
9
23
  redis_cache = ActiveSupport::Cache::RedisCacheStore.new
10
24
  brotli_redis_cache = RailsBrotliCache::Store.new(redis_cache)
25
+ zstd_redis_cache = RailsBrotliCache::Store.new(redis_cache, compressor_class: ZSTDCompressor, prefix: "zs-")
26
+
11
27
  memcached_cache = ActiveSupport::Cache::MemCacheStore.new
12
28
  brotli_memcached_cache = RailsBrotliCache::Store.new(memcached_cache)
29
+ zstd_memcached_cache = RailsBrotliCache::Store.new(memcached_cache, compressor_class: ZSTDCompressor, prefix: "zs-")
30
+
13
31
  file_cache = ActiveSupport::Cache::FileStore.new('/tmp')
14
32
  brotli_file_cache = RailsBrotliCache::Store.new(file_cache)
33
+ zstd_file_cache = RailsBrotliCache::Store.new(file_cache, compressor_class: ZSTDCompressor, prefix: "zs-")
15
34
 
16
35
  json_uri = URI("https://raw.githubusercontent.com/pawurb/rails-brotli-cache/main/spec/fixtures/sample.json")
17
36
  json = Net::HTTP.get(json_uri)
18
37
 
19
38
  puts "Uncompressed JSON size: #{json.size}"
20
39
  redis_cache.write("gz-json", json)
21
- gzip_json_size = redis_cache.redis.get("gz-json").size
40
+ gzip_json_size = redis_cache.redis.with do |conn|
41
+ conn.get("gz-json").size
42
+ end
22
43
  puts "Gzip JSON size: #{gzip_json_size}"
23
44
  brotli_redis_cache.write("json", json)
24
- br_json_size = redis_cache.redis.get("br-json").size
45
+ br_json_size = redis_cache.redis.with do |conn|
46
+ conn.get("br-json").size
47
+ end
25
48
  puts "Brotli JSON size: #{br_json_size}"
26
49
  puts "~#{((gzip_json_size - br_json_size).to_f / gzip_json_size.to_f * 100).round}% improvment"
27
50
  puts ""
28
51
 
52
+ zstd_redis_cache.write("json", json)
53
+ zs_json_size = redis_cache.redis.with do |conn|
54
+ conn.get("zs-json").size
55
+ end
56
+ puts "ZSTD JSON size: #{zs_json_size}"
57
+ puts "~#{((gzip_json_size - zs_json_size).to_f / gzip_json_size.to_f * 100).round}% improvment"
58
+ puts ""
59
+
29
60
  iterations = 100
30
61
 
31
62
  Benchmark.bm do |x|
@@ -43,6 +74,13 @@ Benchmark.bm do |x|
43
74
  end
44
75
  end
45
76
 
77
+ x.report("zstd_memory_cache") do
78
+ iterations.times do
79
+ zstd_memory_cache.write("test", json)
80
+ zstd_memory_cache.read("test")
81
+ end
82
+ end
83
+
46
84
  x.report("redis_cache") do
47
85
  iterations.times do
48
86
  redis_cache.write("test", json)
@@ -57,6 +95,13 @@ Benchmark.bm do |x|
57
95
  end
58
96
  end
59
97
 
98
+ x.report("zstd_redis_cache") do
99
+ iterations.times do
100
+ zstd_redis_cache.write("test", json)
101
+ zstd_redis_cache.read("test")
102
+ end
103
+ end
104
+
60
105
  x.report("memcached_cache") do
61
106
  iterations.times do
62
107
  memcached_cache.write("test", json)
@@ -71,6 +116,13 @@ Benchmark.bm do |x|
71
116
  end
72
117
  end
73
118
 
119
+ x.report("zstd_memcached_cache") do
120
+ iterations.times do
121
+ zstd_memcached_cache.write("test", json)
122
+ zstd_memcached_cache.read("test")
123
+ end
124
+ end
125
+
74
126
  x.report("file_cache") do
75
127
  iterations.times do
76
128
  file_cache.write("test", json)
@@ -84,4 +136,11 @@ Benchmark.bm do |x|
84
136
  brotli_file_cache.read("test")
85
137
  end
86
138
  end
139
+
140
+ x.report("zstd_file_cache") do
141
+ iterations.times do
142
+ zstd_file_cache.write("test", json)
143
+ zstd_file_cache.read("test")
144
+ end
145
+ end
87
146
  end
@@ -115,8 +115,10 @@ module RailsBrotliCache
115
115
  @core_store.fetch_multi(
116
116
  *names, options.merge(compress: false)
117
117
  ) do |name|
118
- compressed(yield(name), options)
119
- end
118
+ compressed(yield(source_cache_key(name)), options)
119
+ end.map do |key, val|
120
+ [source_cache_key(key), uncompressed(val, options)]
121
+ end.to_h
120
122
  end
121
123
 
122
124
  def exist?(name, options = {})
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsBrotliCache
4
- VERSION = "0.6.0"
4
+ VERSION = "0.6.1"
5
5
  end
@@ -13,6 +13,10 @@ describe RailsBrotliCache do
13
13
  ]
14
14
 
15
15
  CACHE_STORE_TYPES.each do |cache_store_types|
16
+ let(:big_enough_to_compress_value) do
17
+ SecureRandom.hex(2048)
18
+ end
19
+
16
20
  describe "Brotli cache has the same API as #{cache_store_types[0].class}" do
17
21
  subject(:brotli_store) do
18
22
  RailsBrotliCache::Store.new(cache_store_types[0])
@@ -32,7 +36,7 @@ describe RailsBrotliCache do
32
36
 
33
37
  it "for #read and #write" do
34
38
  int_val = 123
35
- expect(brotli_store.write("int_val_key", int_val).class).to eq(standard_cache.write("int_val_key", int_val).class)
39
+ expect(brotli_store.write("int_val_key", big_enough_to_compress_value).class).to eq(standard_cache.write("int_val_key", big_enough_to_compress_value).class)
36
40
  expect(brotli_store.read("int_val_key")).to eq(standard_cache.read("int_val_key"))
37
41
 
38
42
  str_val = "str"
@@ -55,16 +59,15 @@ describe RailsBrotliCache do
55
59
  end
56
60
 
57
61
  it "for #fetch" do
58
- val = "123"
59
- expect(brotli_store.fetch("val_key") { val }).to eq(standard_cache.fetch("val_key") { val })
60
- expect(brotli_store.fetch("val_key", force: true) { val }).to eq(standard_cache.fetch("val_key", force: true) { val })
62
+ expect(brotli_store.fetch("val_key") { big_enough_to_compress_value }).to eq(standard_cache.fetch("val_key") { big_enough_to_compress_value })
63
+ expect(brotli_store.fetch("val_key", force: true) { big_enough_to_compress_value }).to eq(standard_cache.fetch("val_key", force: true) { big_enough_to_compress_value })
61
64
  expect(brotli_store.fetch("val_key")).to eq(standard_cache.fetch("val_key"))
62
65
  end
63
66
 
64
67
  it "for #write_multi and #read_multi" do
65
68
  values = {
66
69
  "key_1" => "val_1",
67
- "key_2" => "val_2"
70
+ "key_2" => big_enough_to_compress_value
68
71
  }
69
72
 
70
73
  brotli_store.write_multi(values)
@@ -78,7 +81,7 @@ describe RailsBrotliCache do
78
81
 
79
82
  it "for #fetch_multi" do
80
83
  values = {
81
- "key_1" => "val_1",
84
+ "key_1" => big_enough_to_compress_value,
82
85
  "key_2" => "val_2"
83
86
  }
84
87
 
@@ -98,9 +98,22 @@ describe RailsBrotliCache do
98
98
  end
99
99
 
100
100
  describe "fetch_multi" do
101
+ subject do
102
+ cache_store.fetch_multi(*keys) do |key|
103
+ big_enough_to_compress_value + key
104
+ end
105
+ end
106
+
107
+ let(:keys) { %w[key_1 key_2] }
108
+ let(:response) do
109
+ {
110
+ 'key_1' => big_enough_to_compress_value + 'key_1',
111
+ 'key_2' => big_enough_to_compress_value + 'key_2'
112
+ }
113
+ end
114
+
101
115
  it "works" do
102
- cache_store.fetch_multi("key_1", "key_2", expires_in: 5.seconds) { big_enough_to_compress_value }
103
- expect(cache_store.read("key_1")).to eq big_enough_to_compress_value
116
+ expect(subject).to eq response
104
117
  end
105
118
  end
106
119
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-brotli-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-09 00:00:00.000000000 Z
11
+ date: 2023-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -226,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
226
  - !ruby/object:Gem::Version
227
227
  version: '0'
228
228
  requirements: []
229
- rubygems_version: 3.4.10
229
+ rubygems_version: 3.3.7
230
230
  signing_key:
231
231
  specification_version: 4
232
232
  summary: Drop-in enhancement for Rails cache, offering better performance and compression