Skip to content

Commit

Permalink
Optimize JSON encoding
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
philippthun committed Aug 27, 2021
1 parent 6a850a6 commit 0213551
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 3 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ gem 'net-ssh'
gem 'netaddr', '>= 2.0.4'
gem 'newrelic_rpm'
gem 'nokogiri', '>=1.10.5'
gem 'oj'
gem 'palm_civet'
gem 'posix-spawn', '~> 0.3.15'
gem 'protobuf', '3.6.12'
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ GEM
racc (~> 1.4)
nokogiri (1.12.3-x86_64-linux)
racc (~> 1.4)
oj (3.13.2)
os (1.0.1)
palm_civet (1.1.0)
parallel (1.20.1)
Expand Down Expand Up @@ -553,6 +554,7 @@ DEPENDENCIES
netaddr (>= 2.0.4)
newrelic_rpm
nokogiri (>= 1.10.5)
oj
palm_civet
parallel_tests
pg
Expand Down
20 changes: 17 additions & 3 deletions config/initializers/json.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
require 'active_support/json/encoding'

module CCInitializers
def self.json(_cc_config)
def self.json(cc_config)
if cc_config[:use_optimized_json_encoder]
MultiJson.use(:oj)
Oj::Rails.optimize # Use optimized encoders instead of as_json() methods for available classes.
Oj.default_options = {
bigdecimal_load: :bigdecimal,
}
end

ActiveSupport.json_encoder = Class.new do
attr_reader :options

Expand All @@ -10,10 +18,16 @@ def initialize(options=nil)
end

def encode(value)
if MultiJson.default_adapter == :oj && value.is_a?(VCAP::CloudController::Presenters::V3::BasePresenter)
v = value.to_hash
else
v = value.as_json(options.dup)
end

if Rails.env.test?
MultiJson.dump(value.as_json(options.dup))
MultiJson.dump(v)
else
MultiJson.dump(value.as_json(options.dup), options.merge(pretty: true))
MultiJson.dump(v, options.merge(pretty: true))
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/cloud_controller/config_schemas/base/api_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ class ApiSchema < VCAP::Config
write_key: String,
dataset: String,
},

optional(:use_optimized_json_encoder) => bool,
}
end
# rubocop:enable Metrics/BlockLength
Expand Down
3 changes: 3 additions & 0 deletions lib/cloud_controller/http_response_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ def initialize(message, method, response)

begin
source = MultiJson.load(response.body)
rescue ArgumentError
# Either Oj should raise Oj::ParseError instead of ArgumentError, or MultiJson should also wrap
# ArgumentError into MultiJson::Adapters::Oj::ParseError
rescue MultiJson::ParseError
source = response.body
end
Expand Down

0 comments on commit 0213551

Please sign in to comment.