I'm not sure but for me the "What is Django" section answers the question. For me Django is full of philosophy that seeds a great ecosystem of apps of all sorts with a growing user base nonetheless, and a bunch of brilliant hackers to look up to and inspire for more. Of course if you're into fixing a particular technical issue such as "I want to make an efficient GraphQL server", then even Django works even if it's not necessarily the most fit for X reason. But for "I want to get a web page going with some forms and a database and see where that goes" then Django is definitely enjoyable, and at this point in time where tons of more sophisticated frameworks are born it's clear that Django is still in the game and will be for the next 10 years. So, why not also get more features out of it while we've not been abandoned by all the talented contributors ? It's not because we like Django that we cant haz nice things ;)
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/314d7b71-1bf1-441b-ae49-e4fbeb5e1891%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
That said, I also think it's important to allow the ORM to support both modes in the long term. I truly believe the best way to be able to write async code is to _have the choice to write it_, rather than being made to all the time; if we make people use a separate, async ORM, then we force them to write every view asynchronously, with all the extra danger and thinking that requires. It's much better for Django to do the hard work, and say "hey, if you want to write asynchronously or synchronously, that's fine - it takes literally zero extra effort to go either way".
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAFwN1uqav3JXQA3m%2Bajf0Bd15QQX3JTZTfmH3Hc3ECWyRR3CVg%40mail.gmail.com.
That said, I also think it's important to allow the ORM to support both modes in the long term. I truly believe the best way to be able to write async code is to _have the choice to write it_, rather than being made to all the time; if we make people use a separate, async ORM, then we force them to write every view asynchronously, with all the extra danger and thinking that requires. It's much better for Django to do the hard work, and say "hey, if you want to write asynchronously or synchronously, that's fine - it takes literally zero extra effort to go either way".Slightly off-topic but once we have an async ORM, making it synchronous is not impossible (I believe either Channels or Daphne already have shims that use a worker thread to spin the event loop until a future is fulfilled).
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/402dbe77-44fc-485b-b058-e619a1576ddb%40googlegroups.com.
Hello Andrew,Thanks for your work putting together this plan. Within our constraints, it's a good plan.Regarding templating, I would say it isn't a priority because a developer who knows how to parallelize I/O bound operations will prefer (or at least accept) to perform these operations in the view, not in the template.I'm on the fence about the convention for async APIs. I'm not super excited by spraying async code with _async prefixes. The namespacing approach would allow for cleaner async code. Most Python modules should be either sync or async, not a mix of both styles. But I might be underestimating the importance of explicitness...
I am also not a fan of the approach, but I did err towards being explicit. Jannis suggested what I think might be a nicer approach on Twitter, which is to add an async "proxy object" to access methods with, e.g.:cache.get("foo")cache.async.get("foo")This is still explicit but looks less ugly, and gives us a way in future to make some modules transition to async-by-default (by e.g. supplying cache.sync.get). What do you think?
If you want guaranteed email delivery, that's a task for something like Celery or a third-party API; any method of sending emails in the background in the same process, be it threads or async coroutines, is going to be unreliable as the server may die any time. I don't think it's sensible for Django to try and solve this problem internally, at least not as part of this async push.
I'm a bit confused here, what benefit are you getting from async emails if you're already retrying emails in the background in production ?
I don't think it makes a significant difference from a readability perspective in this example. It does have some advantages, though:
- It could be easier to implement a sync version based on the async one, or vice-versa, if each one has its own class. It will probably be more DRY.
- It could also be a bit more usable by developers, especially in IDEs
Tom Christie, for example, has already started work on an asynchronous ORM. Some of Django's biggest sites don't use the ORM - for example, Instagram.
I don't think it makes a significant difference from a readability perspective in this example. It does have some advantages, though:
- It could be easier to implement a sync version based on the async one, or vice-versa, if each one has its own class. It will probably be more DRY.
- It could also be a bit more usable by developers, especially in IDEs
Also it could provide an alternative solution for the async attribute access problem: `model_instance.async.related_field` could be a Future that, when awaited, resolves to the related field. So you could `await model_instance.async.related_field` instead of having to `select_related`. To be honest I didn't investigate all the consequences of this idea. It seemed worth mentioning, though, even if it turns out to be impractical :-)
I have a question that strays slightly away from the main topic. I have looked at Tom's repos. Is it encode/databases https://github.com/encode/databases that you're referring to?Or do you mean Tom's working on an async ORM that works within Django?
We've always considered that implicit queries on attribute access were an intractable problem. I said it on stage an DjangoCon US 2013. I'm now wondering if I was wrong all along! In an async ORM context, every time we traverse a relation, we could create a Future that would execute the query and resolve to its result. This would require one await per SQL query so we'd still get the benefit of making queries explicit, although to a lesser extent than with an explicit select/prefetch_related.
queryset = Foo.objects.filter(Foo.publish_date <= datetime.date.today())
queryset = fetch_related(queryset[:10], Foo.author) # with a future
results = await queryset.all()
fetch_related(results, Foo.category) # with a result set, returns identity
I have a separate question. Is it possible to get the django 3.0 asgi things into a different package to use with django 2.2?Thanks for the great work.
Hi Andrew (and everybody following the discussion, of course),
First off, thank you for your work here. DEP9 is an excellent technical
document, and it was as easy and pleasant to read as a document of this
scope and depth can be.
Especially the Motivation section was very insightful – it might be
worth moving it up a bit, as I found myself dropping about a third of my
notes and questions from the first half of the DEP after reaching the
motivation section.
Also, discussing the Why first and the How later is a bit better
argumentatively – if I just spent half an hour reading about the How,
I'll start to see the Why as a given, so it's harder to reason about
alternatives upon reaching the motivation section. Maybe that's just me,
though.
The Sequencing section is equally helpful to get a feeling for the
implementation work. It might be worth including a note on additional
future DEPs there, as those are only mentioned in the high level summary
(and in the templating section, I think).
I have a couple of questions and comments – none of which are meant to
criticise the direction of the DEP or arguments. It's just niggles,
really. I also left some comments on the PR that concern only some
phrasing.
The DEP doesn't really include a discussion of potential downsides. Even
if that's not in scope of a DEP, I'd like to ask this here:
- Is there a potential negative impact for Django users who just
continue to use Django? The only mention of this says "Running code in
threads is likely not going to increase performance - the overhead
added will probably decrease it very slightly in the case where you're
just running normal, linear code". Do you have any details on that? I
would have expected some (even just a sentence or two) discussion of
potential downsides in the Rationale section next to the alternatives.
- Is there a potential negative impact on Django if work on this
proposal takes a long time/is abandoned?
Less general remarks:
> Every single feature that is converted to be async internally will also present
> a synchronous interface that is backwards-compatible with the API as it stands
> today (in 2.2), at least for the normal deprecation period.
As it stands, this will sound a lot like "we'll deprecate lots of
synchronous interfaces soon" to people who are afraid of exactly that.
It's probably worth to clarify this here, or to choose different
phrasing, unless that's what you're planning to do.
> This general overview works on nearly all features on Django that need to be
> async, with the exceptions mostly being places where the Python language itself
> does not provide async equivalents to features we already use.
Can you give examples for this? They don't need to be in the draft, I
think, I'd just like to understand this part better.
> Asynchronous views will continue to be wrapped in an ``atomic()`` block by
> default - while this reduces immediate performance gains, as it will lock all
> ORM queries to a single subthread (see "The ORM" below), it is what our users
> will expect and much safer. If they want to run ORM queries concurrently, they
> will have to explicitly opt out of having the transaction around the view using
> the existing ``non_atomic_requests`` mechanism, though we will need to improve
> the documentation around it.
By default, Django's views are not wrapped in ``atomic()`` blocks. This
is only the case if ``ATOMIC_REQUESTS`` is ``True``, which it isn't by
default. Not sure if an off-by-default feature is worth an entire
paragraph here, but in any case, please make it clear that not every
async view will be wrapped in an ``atomic()`` block (unless I'm mistaken
and they will be?).
> In some ways, this
> will end up looking more like Django 1.0 era middleware again from an internal
> perspective.
It might be worth to make it clear that the middleware interface doesn't
change on the user-facing side, though.
> Whenever a
> ``new_connections()`` block is entered, the transactions do not persist inside,
> but transactions can be made inside the ``new_connections()`` block and run
> against those connections.
I think this was the most complicated sentence in the entire document.
It took me several tries to parse it in a way that could be correct.
Could you try to clarify? I think the missing reference for the "the
transactions" and "those connections" probably led to my confusion.
> This means that, at some point, the ``valid`` methods and ``save``, at
> minimum, need to be able to be called in an async fashion.
The ``valid`` methods? Did you mean the ``clean`` (and ``clean_*``)
methods, or am I missing something?
> While Python is not a perfect asynchronous language, and there are some flaws
> in the core design of ``asyncio``,
This leads me to a question I haven't really seen discussed so far: How
stable is the asyncio API by now? In the 3.x releases so far, asyncio
API has shifted quite a bit. I looked through the 3.8 release notes, but
didn't see any major changes (except maybe task names). This is mostly
relevant to figure out how much work we'll have with the support of
future Python version, and/or keeping backwards compatibility.
You're mentioning `asgiref` a lot – do you expect it to become a
dependency of Django? Do you expect any other new dependencies to be
introduced?
Thank you again for your work (and making it through this “light reading”)
Hello,
I'm a little late to the party, thanks for the big overview on this complex matter.
There are lots of thinks I still don't understand though, for example regarding "what it unlocks". What asyncio structures would allow to run several DB queries concurrently safely and easily, that can't be achieved with some threadpool-like mechanism in nowadays' cod ?
Most importantly, I'm not getting why gevent/eventlet-style solutions are systematically being dismissed in favor of asyncio. And the more I read/talk about it, the less I understand what all that hype around asyncio is. This is a whole new language, which forces people to trashbin half of the Python ecosystem, and remake it with similar code but filled with incompatible async/await statements.
...
Granted, I have little experience with Geven and Asyncio, but all experience feedbacks I've read so far mainly insist on minor limitations of greenlets, and on the fact that "people are mainly going with asyncio" (a self-fulfilling prophecy?). Considered the dramatic difference in workload between the two, I'd really love to understand what killer-features justify to go for the "recode everything" solution (or what greenlet limitations would be show-stoppers on the long term).
I wonder about the end-result payoff of this approach. In general, Django/Python code is not going to be I/O bound, which is where asynchronous approaches are going to get the bang for your buck. Even when it comes to DB access—the DB is a lot faster than the python and django code running against the result set. And too much context-switching (as you noted) has painful ramifications for performance.
I can absolutely see why creating a layer that handles asgi, websockets, and http requests asynchronously is going to pay off. Bit time. But I'm less certain that the ORM access will benefit from an asyncio approach. Do we have anything that approaches a hard number that would tell us re-doing the ORM layer in asyncio would get us X% performance benefit?I'm basing my thoughts off this well-reasoned look at performance: https://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/
--
You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/5CVsR9FSqmg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAFwN1urJVeamhLWLLDpkz_-e1fAM59x6b6rzyAV%3DZAUgg9qrvQ%40mail.gmail.com.
Hello,There is something a little scary for me, in changing all the core of Django to async, when this really helps only, imho, a tiny fraction of users : websocket/long polling services, and reddit-like sites with thousands+ hits per second. For most webpages and webservices, async artillery sounds quite overkill.Are cpython threads inefficient ? As far as I know they are only kernel threads constrained by the Gil, so they shouldnt wake up when they are blocked on io syscalls/mutexes (or do they?), and context switches remain acceptable compared to the slowness of python itself.
We used to provide provisioning and automatic authentication for 20 million users, with partner webservices tar-pitting us for sometimes 1mn. The nightmare scenario. But with 2 machines, 1 process by core, and 800 threads by process, it did the job, enough for us to answer millions of hits a day. Without even relying on other no-recoding optimizations like pypy or gevent.Async would certainly have been a relevant techno if we had known in advance that our partners would be so slow, but avoiding the extra complexity burden of this style (where a single buggy dependency can block all requests in a process, where all modules have to be recoded for it) was also a huge benefit. And the limited thread pool also protected our DB from unbearable loads.
It's very nice if a proper async ecosystem emerges in python, but I fear lots of people are currently jumping into it without a need for such performance, and at the expense of lots of much more important matters like robust ess, correctness, compatibility... like it happened for docker and microservices, transforming into fragile bloatwares simple intranets, which just needed a single django codebase deployed in a single container.A few days ago I audited a well used django module, the current user was stored in a global variable (!!!). People might eventually fix that ticket, use threadlocals, and then switch to a future django-async without realizing that the security issue has come back due to the way async works.Still I hope I'm wrong, that the performance gains will prove worth the software fragmentation and complexity brought by asyncio, but I still dont understand them for 99% users... Especially as long as key-in-hand solutions like greenlets exist for power users.
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAFwN1up%2BRzR3FcA8xBPPSfpY_5%2B5bfyZbJ%3DN9G0Ohy9kOGb53A%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAK8PqJHBvv-Gd-%2BQR95NB52zr8meGhwgyFTysgqc1KWdvwP9KA%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAFwN1upqMLyZgtmcqgmYV8whH43SCXJimTCZGJxA4p1D5PRYTA%40mail.gmail.com.
Django 3.0?