Handling IO - design ideas
Next step for miniasync is to make it easy to handle multiple IO calls. I would like in the first instance to be able to manage:
- HTTP requests
- File read/writes
- Email sending
The current syntax, to call co-routines, is:
results = miniasync.run(coro1, coro2, coro2)
I would want something equally simple:
results = miniasync.get(url1, url2, url3)
results = miniasync.read(file1, file2, file3)
results = miniasync.send(email1, email2, email3)
An alernative syntax could be:
results = miniasync.run(
miniasync.get(url1),
miniasync.get(url2)
miniasync.get(url3)
)
Advantage of that syntax is that it's easier to have multiple parameters, say:
results = miniasync.run(
miniasync.write(file1, data1, mode='b'),
miniasync.write(file2, data2, mode='b')
)
rather than, say,
results = miniasync.write(
(file1, data1, 'b'),
(file2, data2, 'b')
)
An other advantage is combining different operations:
results = miniasync.run(
miniasync.post(url, notification),
miniasync.send(emal_address, notification)
)
But the disadvantages are:
- More heavy syntax for the simple tasks
- We can't have code to prepare for the operations. This is an issue for HTTP requests where asynciohttp has a concept a Sessions, which make requests more efficient by re-using pre-warmed sockets for example.
We could offer both version - a sync version and an async version of each call. This would make it possible for users to re-use these functions inside their own async code. Not sure what the best naming convention for having both versions is (I've seen some people prepend the async version with "a", eg. "aget", "aread", etc.)
If we didn't offer both versions, how would people combine operations easily? Sending both an email and posting a tweet sounds like something one would do when sending out notifications. We could use an object of some sort:
results = (miniasync.Combine()
.post(url, notification)
.send(email_address, notification)
.execute()
)
It's very Javascripty, I'm not sure I like it. Another option (which I don't like, but I include for completeness) is a context manager that gathers things to run, and runs them upon exiting:
with miniasync.combine() as combine:
combine.post(url, notification)
combine.send(email_address, notification)
I don't like the fact a line of code after combine.send() would actually run before combine.send is executed. I want miniasync to have very obvious execution paths.