Avoid lock when ecs_compatibility is explicitly specified (#16786) (#16828)

Because a `break` escapes a `begin`...`end` block, we must not use a `break` in order to ensure that the explicitly set value gets memoized to avoid lock contention.

> ~~~ ruby
> def fake_sync(&block)
>   puts "FAKE_SYNC:enter"
>   val = yield
>   puts "FAKE_SYNC:return(#{val})"
>   return val
> ensure
>   puts "FAKE_SYNC:ensure"
> end
>
> fake_sync do
>   @ivar = begin
>     puts("BE:begin")
>   	break :break
>
>   	val = :ret
>   	puts("BE:return(#{val})")
>   	val
>   ensure
>     puts("BE:ensure")
>   end
> end
> ~~~

Note: no `FAKE_SYNC:return`:

> ~~~
> ╭─{ rye@perhaps:~/src/elastic/logstash (main ✔) }
> ╰─● ruby break-esc.rb
> FAKE_SYNC:enter
> BE:begin
> BE:ensure
> FAKE_SYNC:ensure
> [success]
> ~~~

(cherry picked from commit 01c8e8bb55)

Co-authored-by: Ry Biesemeyer <yaauie@users.noreply.github.com>
This commit is contained in:
github-actions[bot] 2024-12-23 10:43:53 -08:00 committed by GitHub
parent dbb06c20cf
commit 51993816fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -9,10 +9,11 @@ module LogStash
def ecs_compatibility
@_ecs_compatibility || LogStash::Util.synchronize(self) do
@_ecs_compatibility ||= begin
# use config_init-set value if present
break @ecs_compatibility unless @ecs_compatibility.nil?
# use config_init-set value if present
@_ecs_compatibility ||= @ecs_compatibility
# load default from settings
@_ecs_compatibility ||= begin
pipeline = execution_context.pipeline
pipeline_settings = pipeline && pipeline.settings
pipeline_settings ||= LogStash::SETTINGS