| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
converts old ID methods to the new abstract store methods in Rack
|
| |
|
|
|
|
|
|
| |
Just include the modules necessary in the Request object to implement
the things we need. This should make it easier to build delegate
request objects because the API is smaller
|
|
|
|
|
|
| |
Escaping and unescaping paths is different than query parameters, and we
need to respect that. This commit uses the new method in Rack to escape
and unescape paths. Fixes #11816
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With changes made in 8363b8 and ae29142 cookies that are mutated on the
request like `cookies.signed = x` were not retained in subsequent tests,
breaking cookie authentiation in controller tests.
The test added demonstrates the issue.
The reason we need to select from non-deleted cookies is because without
checking the `@delete_cookies` the `cookie_jar` `@cookies` will send the
wrong cookies to be updated. The code must check for `@deleted_cookies`
before sending an `#update` with the requests cookie_jar cookies.
This follows how the cookie_jar cookies from the request were updated
before these changes.
|
|
|
|
| |
They are already required in `actionpack/lib/action_dispatch.rb` (L25-L26)
|
|
|
|
|
| |
This `protected` keyword looks like some leftover, since
we are not using explicit receiver, this should go under `private`
|
| |
|
|
|
|
|
| |
I want to implement this with something besides `@env` in the future, so
lets stop directly referencing it.
|
| |
|
|
|
|
|
| |
we already have a request, so we should use the methods on the request
to access the path info information
|
|
|
|
| |
Creates fewer request objects and helps to abstract away from internals
|
| |
|
|
|
|
|
| |
try to remove dependencies on `@env` so we can have more flexible
internals
|
|
|
|
|
| |
This commit allows us to use one request object rather than allocating
multiple request objects to deal with the session.
|
| |
|
|
|
|
|
| |
since we only work with instances of classes, it greatly simplifies the
`Middleware` implementation.
|
|
|
|
|
|
|
|
|
|
| |
Convert things like this:
middleware.use "Foo::Bar"
to this:
middleware.use Foo::Bar
|
|
|
|
|
|
| |
We should do the hard work outside the constructor. Also fix the tests
to not directly construct middleware objects, but to go through the
stack object.
|
|
|
|
|
|
| |
Proc.new will pick up the passed in block, but since it's a default
param, it won't get evaluated unless someone doesn't pass in an app. It
will raise an exception if no block is provided.
|
|
|
|
|
| |
this is another place that we should stop directly accessing the env
hash and let the request object take care of that for us
|
| |
|
|
|
|
|
|
|
| |
again, we want to hide the contents of `env` from the implementation.
Allocate a request object to access the contents of env, but save
allocations due to string literal allocations when accessing the env
hash.
|
|
|
|
|
| |
hide the env key in the request object so that other code doesn't need
to know.
|
|
|
|
|
|
| |
ExceptionWrapper only cares about the backtrace cleaner, so lets just
pass the cleaner to the wrapper. It does not need to know that env
exists or what key the backtrace cleaner is stored in
|
|
|
|
|
|
|
| |
Implement `serve` on the middleware. Nothing can be placed between the
instance of FileHandler and Static because Static instantiates an
instance of FileHandler. IOW there is no reason to implement the `call`
API in this case.
|
| |
|
|
|
|
|
| |
we don't recycle requests anymore, so we shouldn't need to recycle
cookie jars
|
|
|
|
| |
this prevents the middleware from knowing the specific key for the jar
|
| |
|
|
|
|
|
| |
This changes the chained jars to ask the parent jar for the request
object which should eventually call back up to the original jar
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
eventually we will make the cookie jar derive these values from the
request object rather than save a reference to the values
|
|
|
|
|
|
|
|
| |
The cookie jar can just ask the request object for the information it
needs. This allows us to stop allocating hashes for options, and also
allows us to delay calculating values in advance. Generating the
options hash forced us to calculate values that we may never have needed
at runtime
|
|
|
|
|
|
| |
Accessing a request object has nice advantages over accessing a hash.
If you use a missing method name, you'll get an exception rather than a
`nil` (is one nice feature)
|
|
|
|
|
| |
Now that we have encoding strategies, we can just walk the params hash
once to encode as HWIA, and remove nils.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I wrote a utility that helps find areas where you could optimize your program using a frozen string instead of a string literal, it's called [let_it_go](https://github.com/schneems/let_it_go). After going through the output and adding `.freeze` I was able to eliminate the creation of 1,114 string objects on EVERY request to [codetriage](codetriage.com). How does this impact execution?
To look at memory:
```ruby
require 'get_process_mem'
mem = GetProcessMem.new
GC.start
GC.disable
1_114.times { " " }
before = mem.mb
after = mem.mb
GC.enable
puts "Diff: #{after - before} mb"
```
Creating 1,114 string objects results in `Diff: 0.03125 mb` of RAM allocated on every request. Or 1mb every 32 requests.
To look at raw speed:
```ruby
require 'benchmark/ips'
number_of_objects_reduced = 1_114
Benchmark.ips do |x|
x.report("freeze") { number_of_objects_reduced.times { " ".freeze } }
x.report("no-freeze") { number_of_objects_reduced.times { " " } }
end
```
We get the results
```
Calculating -------------------------------------
freeze 1.428k i/100ms
no-freeze 609.000 i/100ms
-------------------------------------------------
freeze 14.363k (± 8.5%) i/s - 71.400k
no-freeze 6.084k (± 8.1%) i/s - 30.450k
```
Now we can do some maths:
```ruby
ips = 6_226k # iterations / 1 second
call_time_before = 1.0 / ips # seconds per iteration
ips = 15_254 # iterations / 1 second
call_time_after = 1.0 / ips # seconds per iteration
diff = call_time_before - call_time_after
number_of_objects_reduced * diff * 100
# => 0.4530373333993266 miliseconds saved per request
```
So we're shaving off 1 second of execution time for every 220 requests.
Is this going to be an insane speed boost to any Rails app: nope. Should we merge it: yep.
p.s. If you know of a method call that doesn't modify a string input such as [String#gsub](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37) please [give me a pull request to the appropriate file](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37), or open an issue in LetItGo so we can track and freeze more strings.
Keep those strings Frozen
![](https://www.dropbox.com/s/z4dj9fdsv213r4v/let-it-go.gif?dl=1)
|
|\
| |
| | |
Concurrent load interlock (rm Rack::Lock)
|
| |
| |
| |
| |
| | |
We can't actually lean on Rack::Lock's implementation, so we'll just
copy it instead. It's simple enough that that's not too troubling.
|
| |
| |
| |
| |
| | |
We don't need to fully disable concurrent requests: just ensure that
loads are performed in isolation.
|
| |
| |
| |
| |
| | |
pass in the instance variable to start decoupling the meat of the parser
from the instance of the middleware
|
| |
| |
| |
| |
| | |
We will always make an assignment to the env hash and eliminate a
conditional
|
|/
|
|
|
| |
If we only deal with proc objects, then we can eliminate type checking
in the parameter parsing middleware
|
| |
|
|
|
|
|
|
| |
This change decouples `cookie_jar` allocation from the request object.
We need this for moving controller tests to integration tests so we can
access the `cookie_jar` object separately.
|
|
|
|
|
|
| |
`ActionDispatch::SSL` changes headers to `Hash`.
So some headers will be broken if there are some middlewares
on ActionDispatch::SSL and if it uses `Rack::Utils::HeaderHash`.
|
| |
|