This commit vastly reduces the impact of auto
explain logging when enabled, while keeping
a negligible cost when disabled.
The first implementation was based on the idea
of subscribing to "sql.active_record" when
needed, and unsubscribing once done. This is
the idea behind AR::Relation#explain. Subscribe,
collect, unsubscribe.
But with the current implementation of notifications
unsubscribing is costly, because it wipes an internal
cache and that puts a penalty on the next event.
So we are switching to an approach where a long-running
subscriber is listening. Instead of collecting the
queries with a closure in a dedicated subscriber, now
we setup a thread local.
If the feature is disabled by setting the threshold
to nil, the subscriber will call a method that does
nothing. That's totally cheap.
Rationale: As discussed with José and Jon, this convenience
shortcut is not clearly justified and it could let the user
thing the disabled EXPLAINs are related to the model instance
rather than being globally disabled.
Revert html_escape to do a single gsub again, but add the "n" flag (no
language, i.e. not multi-byte) to protect against XSS via invalid utf8
Signed-off-by: José Valim <jose.valim@gmail.com>
This reverts commit f6b5046305.
Fear not, the roflscale will return when I have a bit more time and
figure out a better way to do it. (In particular, a way that doesn't
break the build.)
This means we never have to rely on define_method (which is slower and
uses more memory), even when we have attributes containing characters
that are not allowed in standard method names.
(I am mainly changing this because the duplication annoys me, though.)
Also make it actually work.
It slows down all read_attribute accesses to map 'id' to whatever the PK
actually is, inside read_attribute. So instead make sure the necessary
methods are defined and that they redirect wherever they need to go.
Define singleton methods on the attributes module instead. This reduces
method pollution on the actual model classes. It also seems to make
something faster, I am unsure why! O_o
* A Railtie API for registering new exceptions and their respective status code (check Active Record railtie for an example)
* Extraction of ShowExceptions middleware logging and debugging features into a middleware called DebugExceptions
Conflicts:
actionpack/CHANGELOG.md