-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resource Management Story #408
Comments
Here are some examples of how co.defer works in generators. Its hacky without first-class syntax: petkaantonov/bluebird@f944db7#diff-3129285757f0c44eca9973432b3bb15aR704 The Go example would look like this: funcion* test() {
let f = yield openFile("/tmp/test.txt");
co.defer(() => f.close());
n = yield fmt.Fprintln(f, "data")
return n;
} Its possible to patch typescript to make co.defer work with async/await when the target is ES6, but not sure if thats desireable. It would be much nicer if we had official syntax for all this 😀 |
As we were able to get a hold of @1st1 who built this for Python in Europython (yay, thanks a ton @ztane for getting the hold!). I have some directed questions:
|
Hm, nothing comes to mind. I don't think people have any problems implementing asynchronous context managers in Python.
Yes, quite happy. It mirrors the API for synchronous context managers in Python:
As for changing/extending the API—we don't have any issues with the current one, so no.
I can only answer for Python: no, there are no type safety concerns as far as I know.
Could you please clarify this one?
In general we don't care about GC when we create (async-)context managers in Python. Both |
On the language side, there is ongoing work in this area in @rbuckton's |
Awesome @littledan - @rbuckton reading that proposal I'm not sure it's safe in terms of resource management - especially with multiple async resources acquired - Consider reading the debates in petkaantonov/bluebird#65 and the Python async context manager work mentioned above. Basically - safety with multiple resources is very hard - so If there is better place to provide feedback please do let me know and I'd love to help. |
@1st1 thanks a lot, really appreciate it!
That's awesome to hear, thanks!
We don't have one for JavaScript yet - but acquire and exit semantics like
Thanks, very helpful
Sorry, rereading that it wasn't clear - I'm asking what to do if Is there anything reasonable to do in this case?
Good :) |
@benjamingr I encourage you to file issues on that proposal repository--that will make your feedback more visible to everyone engaging in TC39. |
Both synchronous and asynchronous context manager protocols work exactly the same in Python. The only difference is that synchronous protocol calls Now I'll try to showcase all error cases and explain how Python handles them using a synchronous protocol. Sorry if you know all of this stuff already! For example, for the given code: class Foo:
def __enter__(self):
1 / 0
def __exit__(self, *e):
print('exiting')
with Foo():
pass Python will output
I.e. any exception that happens while we are entering the context manager doesn't get intercepted by Now let's make the wrapped code to raise an error: class Foo:
def __enter__(self):
pass
def __exit__(self, *e):
print('exiting', e)
with Foo():
1 / 0 Now the output is this:
So an exception has occurred, got passed to the Now, if we add class Foo:
def __enter__(self):
pass
def __exit__(self, *e):
print('exiting', e)
return True
with Foo():
1 / 0 Running it will show you:
Now, we're getting to the meat of your question. Let's raise another error in class Foo:
def __enter__(self):
pass
def __exit__(self, *e):
print('exiting', e)
1 + 'aaa'
with Foo():
1 / 0 Now we have:
So another exception— This mechanism duplicates the behaviour of how try:
1/0
except:
1 + 'aa' Will produce
Hopefully this explains how CMs work in Python (and I hope I correctly interpreted your question!) :) |
Thanks, that clears everything entirely. The analogy for us would be to attach a |
I made a repo with python-like with statements for deno: https://github.com/hayd/deno-using |
We cannot automatically clean up resources. They must be destroyed by the caller. |
Looks like this may be finding its way into TS soon microsoft/TypeScript#54505 |
how can I try out |
Hey,
Thinking about the I/O stuff made me realize that since we don't have
defer
in JavaScript and we have exceptions so:Could be:
Which unlike
defer
doesn't really stack up too nicely with multiple files:This sort of code is very hard to write correctly - especially if resources are acquired concurrently (we don't await before the first createFile finishes to do the second) and some of them fail.
We can do other stuff instead for resource management:
using
function from deno and have a "real" resource" story.Here is what the above example looks like with exposing a
using
:We wrote some prior art in bluebird in here - C# also does this with
using
(I asked before definingusing
in bluebird and got an interesting perspective from Eric). Python haswith
and Java hastry with resource
.Since this is a problem "browser TypeScript" doesn't really have commonly I suspect it will be a few years before a solution might come from TC39 if at all - issues were opened in TypeScript but it was deemed out of scope. Some CCs to get the discussion started:
defer
for bluebird coroutines andusing
with me.We also did some discussion in Node but there is no way I'm aware of for Node to do this nicely that won't be super risky - Deno seems like the perfect candidate for a safer API for resource management.
@ry if you prefer this as a PR with a concrete proposal for either approach let me know. Alternatively if you prefer the discussion to happen at a later future point let me know.
The text was updated successfully, but these errors were encountered: