Closed mscrivo closed 2 months ago
@hsbt any idea?
I will look at next week.
@mscrivo do you see the same without YJIT? How does 3.3.4 behave?
Ah I misspoke, we're already using 3.3.4. I'll have to put together a test with the new version and YJIT disabled, or try and see if I can repro on my dev machine. Will let you know if I have anything interesting to share on that front.
Just chiming in that we also have this problem with 3.0.2
, so I've locked things to 3.0.1
until 3.0.3
is released.
I've noticed the same issue within Grape which depends on mustermann-grape
. While profiling some code, I found that the memory allocation skyrocketed from 2.0.2 to 3.0.2
mustermann 2.0.2
Total allocated: 13844660 bytes (151009 objects)
Total retained: 478500 bytes (1419 objects)
mustermann 3.0.0
Total allocated: 13844660 bytes (151009 objects)
Total retained: 478500 bytes (1419 objects)
mustermann 3.0.1
Total allocated: 112875956 bytes (312625 objects)
Total retained: 478500 bytes (1419 objects)
mustermann 3.0.2
Total allocated: 310938548 bytes (635857 objects)
Total retained: 478500 bytes (1419 objects)
allocated memory by location
-----------------------------------
46772544 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:504
36381072 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:500
33332208 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:501
22451520 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:505
21656544 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:506
12544896 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:515
10015824 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:520
9832368 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:451
8290464 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:519
6473376 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:453
5346432 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:473
5263440 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:517
5136768 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:448
4599504 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:521
4599504 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:522
4590768 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:446
4333056 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:339
4333056 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:497
4018560 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:441
3922464 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:518
3900624 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:514
3524976 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:513
3468192 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:510
2891616 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:516
2856672 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:509
2795520 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:419
2795520 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:424
2795520 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:438
2321000 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/translator.rb:106
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:388
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:394
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:398
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:402
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:416
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:434
1397760 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:436
990720 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/parser.rb:129
931840 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:292
731240 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/translator.rb:42
698880 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:386
698880 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:414
698880 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:443
698880 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:99
582400 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/compiler.rb:17
570752 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/translator.rb:123
511489 /Users/eproulx/code/grape/lib/grape/router/base_route.rb:26
467344 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/translator.rb:108
432840 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/compiler.rb:129
411480 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mustermann-3.0.2/lib/mustermann/ast/translator.rb:114
349440 /Users/eproulx/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/uri-0.13.1/lib/uri/rfc2396_parser.rb:296
You can execute a complete memory profiler from this script
require 'grape'
require 'memory_profiler'
class API < Grape::API
default_format :json
params do
requires :name, allow_blank: false
end
get '/disallow_blank'
params do
optional :name, type: String, allow_blank: false
end
get '/opt_disallow_string_blank'
params do
optional :name, allow_blank: false
end
get '/disallow_blank_optional_param'
params do
requires :name, allow_blank: true
end
get '/allow_blank'
params do
requires :val, type: DateTime, allow_blank: true
end
get '/allow_datetime_blank'
params do
requires :val, type: DateTime, allow_blank: false
end
get '/disallow_datetime_blank'
params do
requires :val, type: DateTime
end
get '/default_allow_datetime_blank'
params do
requires :val, type: Date, allow_blank: true
end
get '/allow_date_blank'
params do
requires :val, type: Integer, allow_blank: true
end
get '/allow_integer_blank'
params do
requires :val, type: Float, allow_blank: true
end
get '/allow_float_blank'
params do
requires :val, type: Integer, allow_blank: true
end
get '/allow_integer_blank'
params do
requires :val, type: Symbol, allow_blank: true
end
get '/allow_symbol_blank'
params do
requires :val, type: Grape::API::Boolean, allow_blank: true
end
get '/allow_boolean_blank'
params do
requires :val, type: Grape::API::Boolean, allow_blank: false
end
get '/disallow_boolean_blank'
params do
optional :user, type: Hash do
requires :name, allow_blank: false
end
end
get '/disallow_blank_required_param_in_an_optional_group'
params do
optional :user, type: Hash do
requires :name, type: Date, allow_blank: true
end
end
get '/allow_blank_date_param_in_an_optional_group'
params do
optional :user, type: Hash do
optional :name, allow_blank: false
requires :age
end
end
get '/disallow_blank_optional_param_in_an_optional_group'
params do
requires :user, type: Hash do
requires :name, allow_blank: false
end
end
get '/disallow_blank_required_param_in_a_required_group'
params do
requires :user, type: Hash do
requires :name, allow_blank: false
end
end
get '/disallow_string_value_in_a_required_hash_group'
params do
requires :user, type: Hash do
optional :name, allow_blank: false
end
end
get '/disallow_blank_optional_param_in_a_required_group'
params do
optional :user, type: Hash do
optional :name, allow_blank: false
end
end
get '/disallow_string_value_in_an_optional_hash_group'
resources :custom_message do
params do
requires :name, allow_blank: { value: false, message: 'has no value' }
end
get
params do
optional :name, allow_blank: { value: false, message: 'has no value' }
end
get '/disallow_blank_optional_param'
params do
requires :name, allow_blank: true
end
get '/allow_blank'
params do
requires :val, type: DateTime, allow_blank: true
end
get '/allow_datetime_blank'
params do
requires :val, type: DateTime, allow_blank: { value: false, message: 'has no value' }
end
get '/disallow_datetime_blank'
params do
requires :val, type: DateTime
end
get '/default_allow_datetime_blank'
params do
requires :val, type: Date, allow_blank: true
end
get '/allow_date_blank'
params do
requires :val, type: Integer, allow_blank: true
end
get '/allow_integer_blank'
params do
requires :val, type: Float, allow_blank: true
end
get '/allow_float_blank'
params do
requires :val, type: Integer, allow_blank: true
end
get '/allow_integer_blank'
params do
requires :val, type: Symbol, allow_blank: true
end
get '/allow_symbol_blank'
params do
requires :val, type: Grape::API::Boolean, allow_blank: true
end
get '/allow_boolean_blank'
params do
requires :val, type: Grape::API::Boolean, allow_blank: { value: false, message: 'has no value' }
end
get '/disallow_boolean_blank'
params do
optional :user, type: Hash do
requires :name, allow_blank: { value: false, message: 'has no value' }
end
end
get '/disallow_blank_required_param_in_an_optional_group'
params do
optional :user, type: Hash do
requires :name, type: Date, allow_blank: true
end
end
get '/allow_blank_date_param_in_an_optional_group'
params do
optional :user, type: Hash do
optional :name, allow_blank: { value: false, message: 'has no value' }
requires :age
end
end
get '/disallow_blank_optional_param_in_an_optional_group'
params do
requires :user, type: Hash do
requires :name, allow_blank: { value: false, message: 'has no value' }
end
end
get '/disallow_blank_required_param_in_a_required_group'
params do
requires :user, type: Hash do
requires :name, allow_blank: { value: false, message: 'has no value' }
end
end
get '/disallow_string_value_in_a_required_hash_group'
params do
requires :user, type: Hash do
optional :name, allow_blank: { value: false, message: 'has no value' }
end
end
get '/disallow_blank_optional_param_in_a_required_group'
params do
optional :user, type: Hash do
optional :name, allow_blank: { value: false, message: 'has no value' }
end
end
get '/disallow_string_value_in_an_optional_hash_group'
end
end
report = MemoryProfiler.report do
API.compile!
end
report.pretty_print
Anyone in this thread that want this fixed please help at https://github.com/sinatra/mustermann/pull/141#discussion_r1729532052
v3.0.3 released with fix, please report back if it has resolved your issues!
It resolved our issue :)
After upgrading from 3.0 to 3.0.2, we notice crashes during startup in our test environment. The pods were using an order of magnitude more CPU on startup than before. Upon profiling, we saw this:
and this is what our CPU usage looked like before, after upgrade, and after reverting:
We don't use mustermann explicitly, just implicitly via usage of sinatra.
Some notes about our env:
Ruby 3.3.3 with YJIT enabled running in x64 docker image latest Sinatra + Puma versions