question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Store single request object in scope

See original GitHub issue

I’ve thought about doing so with regard to the templating, so that it does not have to be passed in via context, but https://github.com/encode/starlette/issues/495 looks like it would also help fixing state in this regard.

For templating it would be about saving the request there, and this could then be used instead of creating new objects then.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
blueyedcommented, Sep 10, 2019

@tomchristie Any feedback on my previous comment?

I’ve noticed this to be a problem again with request.state, where it would create new State objects for “new” Request objects (created via middleware and app for the same scope).

I am using a lazy property on State (via descriptor), and it would be good to have it only being created once really then. The workaround is to store/cache it on the request.state dict additionally.

2reactions
dmontagucommented, Sep 12, 2019

Related – I think this design where the request gets recreated from the scope (in request_response, which may be called multiple times over the life of the request), but also holds some private cached state that is NOT carried over when the request is re-created (e.g., request._body) is the source of various confusion/surprising behavior, especially with middleware.

I could understand if the intention was to actively discourage conflicting designs (e.g., if they are viewed as anti-patterns), but I think 1) in at least some cases, legitimate approaches are running into issues, and 2) either way, it is currently relatively difficult to figure out the source of the problem, and requires digging into the framework internals.


Directionally, would there be support for a better API for transferring the cached state of the Request (e.g., request._is_stream_consumed, request._body, request._json, etc.) when creating a new Request?

I had a couple ideas about approaches to this:

  1. Store any framework-internal request state in a separate object (perhaps similar to requests.State) that is stored on/read from the scope just like the current request.state, just using a different name (e.g., self.scope['_starlette_state']).

  2. Approaches involving changes to the structure of scope['state']. (These should maybe be ignored outright if starlette should not be imposing any structure on scope['state']; I’m not sure if ASGI says anything specific about the use of that property of the scope.)

    1. Storing starlette-internal state in a low-chance-of-collision key (e.g., request.state.__starlette_state__ or similar) .

    2. Changing the internal structure of the dictionary stored in self.scope['state'] (or equivalently State._state) so that there are two top-level keys: internal and custom (or similar), each holding a dict. The current API (request.state.__getattr__, etc.) would then actually operate on the dict stored in self._state['custom'], and object.__getattr__(request.state, '_state')['internal'] could be used to access the internal state dict. (Admittedly the use of object.__getattr__ is a little awkward, but it would allow a change to the dict structure without a breaking API change.)

    3. The same modified structure of the dict stored in the request as described above, but adding a breaking API change to requests.State so that custom state is actually stored on an attribute State.custom, and framework internal state is stored on State.internal. (So request.state.custom would replace request.state.)

Thoughts?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using the request scope to store an object - Stack Overflow
Using data from the post object, I need to validate the vote object across multiple criteria and several functions. The only way I...
Read more >
4.4 Bean scopes - Spring
Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its...
Read more >
Injection scopes | NestJS - A progressive Node.js framework
You can do this by injecting the REQUEST object. import { Injectable, Scope, Inject } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; ......
Read more >
Using IndexedDB - Web APIs - MDN Web Docs
Object stores are created with a single call to createObjectStore() . The method takes a name of the store, and a parameter object....
Read more >
How do I work with per-request lifetime scope?
Option 1: Change your InstancePerRequest() registrations to be InstancePerLifetimeScope() . Most applications don't create their own nested unit-of-work ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found