-
Notifications
You must be signed in to change notification settings - Fork 63
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
Adds a connection pool #52
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks great! I've done a quick cursory review, will do an in-depth one when the PR is closer to the completion.
I like this. Let's disable |
We don't want to support subclassing. The only reason AwaitConnection is even exported is typing, and I think I'll fix that some other way (like exporting only the type via |
Why should it be resumed? The exception just crashes the |
I looked more into this, and my understanding was wrong. This test wanted to reproduce this one in Python: async def test_pool_handles_transaction_exit_in_asyncgen_1(self):
pool = await self.create_pool(min_size=1, max_size=1)
async def iterate(con):
async with con.transaction():
for record in await con.fetchall("SELECT {1, 2, 3}"):
yield record
class MyException(Exception):
pass
with self.assertRaises(MyException):
async with pool.acquire() as con:
agen = iterate(con)
try:
async for _ in agen: # noqa
raise MyException()
finally:
await agen.aclose()
await pool.aclose() My understanding is that when The same doesn't happen in the TypeScript code I wrote: my mistake was thinking that a Anyway, since the JS driver doesn't have something like the Python driver transaction context manager, there is nothing to test here. |
The code doesn't magically resume. It's caused by the Here's an equivalent JS code: async function *iter() {
let i = 0;
try {
while(1) {
await new Promise(resolve => setTimeout(resolve, 1000));
yield i++
}
}
finally {
console.log('in finally')
await new Promise((r) => {
setTimeout(() => {
console.log('finally done')
}, 1000)
})
}
}
async function main() {
const it = iter();
try {
for await (let i of it) {
console.log('>>>', i);
throw new Error;
}
}
finally {
await it.return()
}
}
main() We'll need to think how to implement |
Unless I am wrong, the Earlier today I tried the following piece of code, and the code in the import asyncio
class AsyncContext:
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc, tb):
# And we get here, too
print("And here, too")
class MyException(Exception):
pass
async def iterate(times):
async with AsyncContext():
try:
for x in range(times):
await asyncio.sleep(0.01)
yield x
except Exception as ex:
# We never get here!!
print("Not here")
finally:
# We get here...
print("We get here...")
async def main():
async for item in iterate(10):
print(item)
if item > 3:
raise MyException()
asyncio.run(main()) Produces the output:
|
Yes, it's still a todo.
Because asyncio uses https://docs.python.org/3/library/sys.html#sys.set_asyncgen_hooks to call |
@1st1 a few days ago I wanted to propose something like this for transactions (you would find it the edit history of the description of this PR). I then removed this part of text because it's a different topic than connection pooling, and deserves a dedicated PR. For example, if added to the async transaction<T>(
action: (connection: AwaitConnection) => Promise<T>
): Promise<T> {
let result: T;
await this.execute("START TRANSACTION");
try {
result = await action(this);
// All done - commit.
await this.execute("COMMIT");
} catch (err) {
await this.execute("ROLLBACK");
throw err;
}
return result;
} |
Yes, that's the gist of it. There are a few arguments that the function should accept (basically allowing tuning of the transaction parameters), but we can nail that in another PR. This PR is still in draft, I assume it's not yet ready for a final review? (just asking) |
The only missing is the documentation: I wrote it but I didn't see it yet on the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. I've left a few comments, Roberto. Thanks for working on this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there! Looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix the remaining comments. And don't forget to squash into 1 commit before merging.
Excellent job!
The code mostly replicates the logic of the Python driver implementation.