Repository navigation
[mod_event_socket] Look up myevents headers once per event instead of once per listener - #3233
Draft
disolaterX wants to merge 1 commit into
Draft
disolaterX wants to merge 1 commit into
disolaterX wants to merge 1 commit into
Conversation
… once per listener event_handler() fetched the unique-id and Job-Owner-UUID headers inside the listener loop for every myevents listener. Each lookup walks the event's header list, so an event cost about two list scans per myevents listener while globals.listener_mutex was held. Fetch both headers once before the loop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
event_handler()in mod_event_socket runs every event past every listener while holdingglobals.listener_mutex. For each listener withLFLAG_MYEVENTS, it calls:switch_event_get_header(event, "unique-id")switch_event_get_header_nil(event, "Job-Owner-UUID")Each call ends in
switch_event_get_header_ptr(), which walks the event's header list linearly. Channel events often carry more than 100 headers. The result is the same for every listener, but it is computed again for each one.Job-Owner-UUIDis only added toBACKGROUND_JOBevents frombgapi(mod_event_socket.c,api_exec). On channel events the lookup scans the whole list and finds nothing. With Nmyeventslisteners, each event costs about 2N header-list scans.This is the common setup for outbound ESL: one socket per call, each sending
myevents.Measurements (reporter's)
These come from a production system on a88d069 and a local repro. I have not measured on current master.
myevents.perfsample of the dispatch thread showedswitch_event_get_header_ptrat 48% andevent_handlerat 14%.myeventssockets drove the thread to 95-104% CPU and delivered 6,930 events 1 s or more late.Fix
Look up both headers once per event, before taking the listener mutex. The loop uses the cached values.
Why behavior is unchanged
uuidis still the rawswitch_event_get_header()result, so it can be NULL. The!uuidcheck is unchanged.job_owner_uuidis still theswitch_event_get_header_nil()result, so it is""when the header is absent. Thestrcmp()sees the same value as before.event. Listeners get aswitch_event_dup()clone. The header pointers stay valid for the whole call.sendassignments are unchanged.One tradeoff: each event now pays two header lookups even when no listener uses
myevents. Before, those lookups only ran formyeventslisteners that passed the earlier checks. Two scans per event is small next to the 2N it replaces.Out of scope
The loop still visits every listener for every event under the global mutex, and the filter-header loop still runs per listener. Indexing
myeventslisteners by session UUID would remove the per-listener walk. That is a larger change, and I'd rather discuss it separately.Testing
clang -fsyntax-only -Wall -Wextra -Wshadow -Wdeclaration-after-statementonmod_event_socket.cagainst an unconfigured tree: no errors, and no warnings inevent_handler(). Warnings were identical before and after the change. (macOS, Apple clang 21.switch_am_config.hwas stubbed and theSWITCH_*_T_FMTmacros were defined by hand, because the tree was not configured.)tests/unit/test_mod_event_socket.c. Its tests cover content-length handling andsendevent, notmyeventsfiltering.