Comments (8)
Events are generally fire-and-forget, so it doesn't really make sense to have any sort of asynchronous-specific support. A function is a function. You can call it whenever you want, and deal with the fallout how you will. Moreover, this is a pretty cut-and-dry implementation of nodejs-style EEs, and I don't really want to stray too far from that.
In other words, I'm not really interested in supporting any features beyond what's already implemented, but I can still talk use case with you, if you think I might have a suggestion in terms of alternate patterns.
from pyee.
(There's also the odd chance that I'm missing something due to unfamiliarity with how python implements futures/etc)
from pyee.
Not sure with what you mean with fire-and-forget, since EventEmitter has synchronous behaviour.
emit
only returns execution when all handlers are called instead of using something like yield from
handler which would allow to really fire the event and forget what will happen next, without having to wait for the handler to end execution.
I understand that this has a natural solution in nodejs by using setImmediate, which isn't as natural in python, since there isn't by default an event loop.
If you feel like sticking to EventEmitter like it exists in nodejs, there's no problem.
from pyee.
I don't follow. What I mean is that no result from any actions your EE takes are retained, so the function handler can easily kick off an asynchronous action no problem. Like in javascript you would just do
ee.on('event', (data) => {
// This schedules an async action, but the actual meat of this function beyond validation
// happens on a subsequent tick, and the EE's handler doesn't do anything with the
// result (this is what I mean by "fire and forget")
doSomeAsyncThing((err) => {
if (err) throw err; // Whatever
console.log('did the thing');
});
});
and you're off to the races! I have to assume that in python you would do something similar. Looking at [https://docs.python.org/3/library/asyncio-task.html#example-hello-world-coroutine](python 3's docs for asyncio) I assume you'd just make some calls to loop
with some coroutines.
But, out of curiosity, what would an example of your proposal Look Like? Maybe seeing a code sample will make this make more sense.
from pyee.
I'll provide you an example and explain the nature of async
and await
.
import asyncio
import pyee
ee = pyee.EventEmitter()
async def sleep(seconds):
print('abc')
await asyncio.sleep(seconds)
print('dow')
ee.on('test', sleep)
async def start():
print("I will emit")
ee.emit('test', 2)
print("I have emitted")
await asyncio.sleep(10)
loop = asyncio.get_event_loop()
loop.set_debug(True)
loop.run_until_complete(start())
print ('done')
If you run this snippet you can see that you'll receive an error because I've set_debug
to True
on the event loop, if you disable you'll just get the same message as a warning.
The reason for this is that an async
function is a coroutine which returns the execution to its caller after it is invoked returning a future. If this future is not await
ed (or yield
ed) the code will simply not run.
This doesn't need to occur imediately, you can retrieve the future and wait for it later on, even though the stream of execution will temporarily stop (which seems like synchronous code) the reality is that if there is any other stream of execution running concurrently it will be able to continue while this is waiting.
This is highly similar to the ES proposal here
My proposal to change this would be to have an emit_async
that would be a coroutine that would await
handlers instead of just invoking them, that could itself be await
ed. There would also be some changes on the once
wrapper that would still work as it does now, but would behave differently when the handler is a coroutine.
I understand if you don't want to pursue this path, and in that case I will be more than happy to implement a version of this code. I'm just sharing this because I really love the observer pattern, and this was one of the cleanest implementations of it that I've found. But since I'm embracing the asynchronous side of python, which makes sense but breaks with some of the current establishment, I'd like to contribute with your effort.
from pyee.
So what you're saying is that we'd "like" to see the following (because async/await -> futures is the async io abstraction in python)
I will emit
abc
I have emitted
dow
done
but right now it prints
I will emit
abc
dow
I have emitted
done
?
Is there a way to switch on whether something is a couroutine/future-generating-function rather than a Boring Function, so that we don't need an alternate implementation? Is there a way to explicitly make it so you don't have to await (or maybe even can't await) the ee call (it sounds like you might have to in this proposal)?
You made comparisons to JavaScript's async/await, which I believe behind the scenes are just packing/unpacking promises (and yield/generators with iterators). Arguably, shouldn't your function handlers just be more explicit about this? I haven't heard of anyone making similar proposals for node, and promisified-by-default core modules are certainly being discussed.
from pyee.
This looks relevant http://stackoverflow.com/questions/37278647/fire-and-forget-python-async-await
from pyee.
I want to use https://docs.python.org/3.5/library/types.html#types.CoroutineType to switch on whether @ee.on is decorating a coroutine or a regular function (note: do I want to switch on generators for completeness?), and then use https://docs.python.org/3/library/asyncio-task.html#asyncio.ensure_future (or possibly an overridable version of this?) with a possible override to schedule coroutines to run.
Something like,
@ee.on('fire')
async def fire_and_forget():
await async_things()
// from somewhere
@ee.emit('fire')
loop.close()
I think? Still learning how the event loop works.
from pyee.
Related Issues (20)
- type-safe TypedEventEmitter implementation HOT 1
- Wrap captured exceptions in a PyeeError HOT 3
- [Regression]: EventEmitter.listeners("foo") throws if no listener exists HOT 2
- Regression: Docs on RTD are Broken HOT 1
- Automate RTD Build HOT 1
- Adopt pyproject.toml HOT 1
- Add .readthedocs.yaml HOT 1
- The 9.0.4 release in pypi isn't tagged in git HOT 2
- 9.0.4: pytest warnings HOT 5
- 9.0.4: sphinx warnings `reference target not found` HOT 6
- async lock error HOT 1
- AsyncIOEventEmitter should keep a reference to scheduled futures HOT 5
- RFE: is it possible to start making github releases?🤔 HOT 3
- Problems with Python 3.12 HOT 2
- Generate non-HTML (man page) docs (with sphinx) HOT 10
- Backfill CHANGELOG
- OSX Issue module 'select' has no attribute 'epoll' HOT 1
- Recommend error handling HOT 5
- Emit can be error HOT 1
- pyee release 9.0.x
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyee.