Skip to content

Commit e5076b3

Browse files
committed
Optimize JSON encoding
- Add 'oj' gem. - Introduce optional 'use_optimized_json_encoder' config property. - If 'use_optimized_json_encoder' is true, use Oj (optimized for Rails) and omit 'as_json' calls for all Presenters.
1 parent 963e568 commit e5076b3

File tree

5 files changed

+25
-3
lines changed

5 files changed

+25
-3
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ gem 'net-ssh'
2525
gem 'netaddr', '>= 2.0.4'
2626
gem 'newrelic_rpm'
2727
gem 'nokogiri', '>=1.10.5'
28+
gem 'oj'
2829
gem 'palm_civet'
2930
gem 'posix-spawn', '~> 0.3.15'
3031
gem 'protobuf', '3.6.12'

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ GEM
308308
racc (~> 1.4)
309309
nokogiri (1.12.4-x86_64-linux)
310310
racc (~> 1.4)
311+
oj (3.13.2)
311312
os (1.0.1)
312313
palm_civet (1.1.0)
313314
parallel (1.20.1)
@@ -552,6 +553,7 @@ DEPENDENCIES
552553
netaddr (>= 2.0.4)
553554
newrelic_rpm
554555
nokogiri (>= 1.10.5)
556+
oj
555557
palm_civet
556558
parallel_tests
557559
pg

config/initializers/json.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
require 'active_support/json/encoding'
22

33
module CCInitializers
4-
def self.json(_cc_config)
4+
def self.json(cc_config)
5+
if cc_config[:use_optimized_json_encoder]
6+
MultiJson.use(:oj)
7+
Oj::Rails.optimize # Use optimized encoders instead of as_json() methods for available classes.
8+
Oj.default_options = {
9+
bigdecimal_load: :bigdecimal,
10+
}
11+
end
12+
513
ActiveSupport.json_encoder = Class.new do
614
attr_reader :options
715

@@ -10,10 +18,16 @@ def initialize(options=nil)
1018
end
1119

1220
def encode(value)
21+
if MultiJson.default_adapter == :oj && value.is_a?(VCAP::CloudController::Presenters::V3::BasePresenter)
22+
v = value.to_hash
23+
else
24+
v = value.as_json(options.dup)
25+
end
26+
1327
if Rails.env.test?
14-
MultiJson.dump(value.as_json(options.dup))
28+
MultiJson.dump(v)
1529
else
16-
MultiJson.dump(value.as_json(options.dup), options.merge(pretty: true))
30+
MultiJson.dump(v, options.merge(pretty: true))
1731
end
1832
end
1933
end

lib/cloud_controller/config_schemas/base/api_schema.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ class ApiSchema < VCAP::Config
350350
write_key: String,
351351
dataset: String,
352352
},
353+
354+
optional(:use_optimized_json_encoder) => bool,
353355
}
354356
end
355357
# rubocop:enable Metrics/BlockLength

lib/cloud_controller/http_response_error.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ def initialize(message, method, response)
1010

1111
begin
1212
source = MultiJson.load(response.body)
13+
rescue ArgumentError
14+
# Either Oj should raise Oj::ParseError instead of ArgumentError, or MultiJson should also wrap
15+
# ArgumentError into MultiJson::Adapters::Oj::ParseError
1316
rescue MultiJson::ParseError
1417
source = response.body
1518
end

0 commit comments

Comments
 (0)