> My ideal solution is one that allows both approaches, and I'd like to 
investigate that further. I think you're getting closer to the sort of 
thing I'm imagining with the uvcorn designs, but I feel like there's still 
something a little extra that could be done so it's possible to offload 
over a network easily (as you mention, letting consumers go to channel 
layers).

Indeed. Centering on the consumer interface doesn't mean that using a 
channel layer isn't an option, just that it's not the base case. It also 
composes really nicely, in the same way as WSGI middleware eg...

app = router({
    'http.request': wsgi_adapter(wsgi_app),
    'websocket.*': redis_channel_layer(...)
})

>  If we end up with one format for channel names and messages that is 
spread across two consumption forms (in-process async and cross-process 
channel layers), I think that would still be a useful enough standard and 
make a lot more people happy.

Yes. I'm not sure if there aren't also reasonable ways to have standard 
non-asyncio frameworks deployed directly behind a server, too. Personally 
I'm looking at using your work to fill the gap of having no WSGI equivalent 
in the asyncio framework space.

> I wish there was a nicer way to achieve this than having send_async() and 
send_group_async() methods (etc.), but the only other alternative I see is 
having the methods all mirrored on an .async object, as in 
"channel_layer.async.send()". I'm not sure how I feel about that - thoughts?

First thought is that the same issue likely applies to a bunch of the 
extension methods. That's a good argument in favour of keeping the API 
surface area as minimal as possible. I'm still keen on an API that only 
exposes data and channel send/receive primitives (and associated error 
handling), and simply doesn't allow for anything beyond that.

The naming aspect has plenty of bikeshedding potential. My current 
preference probably sounds a little counter-intuitive, in that I'd be happy 
to see synchronous and asyncio version of the interface be two incompatible 
takes on the same underlying interface. ie. name them send() and receive() 
in *both* cases. You don't ever want to expose the sync version to an 
asyncio framework, or vice versa.

Asyncio essentially introduces a language within a language, eg. it 
wouldn't be unreasonable to see an `apython` interpreter in the future, 
that fully replaced all the incompatible parts of the standard library with 
coroutine equivalents, so I wouldn't have a problem with treating it almost 
as two separate language implementations against the same spec. I don't 
think it's worth getting hung up on resolving this aspect just yet tho. 
Less contentious would be at least asking the question "should we treat the 
interface as asyncio-first (eg. send/send_blocking) or sync-first 
(send/send_async)?"

Cheers,

  Tom

-- 
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 [email protected].
To post to this group, send email to [email protected].
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/0ffcaeca-9066-4351-aebb-11d826e6a215%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to