Skip to content
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

GIT-1630: add basic signal infra #2041

Closed

Conversation

harshanarayana
Copy link
Contributor

@harshanarayana harshanarayana commented Feb 28, 2021

@ahopkins / @sanic-org/sanic-core-devs This is in no way an attempt to discard the PR you already have in place, but during my break from all the community, I had a different implementation in mind than my original DRAFT. The migration to sanic-router made that way more easier. The whole idea of Mixin is coming to the resume incredibly well.

This is still an early draft of the changes and if you don't mind, I would like to pick this back up in the coming days as I am trying to get back to the community and a familiar implementation requirement might be a good thing to start with.

from sanic import Sanic
from sanic.response import json
from sanic.signals import SignalData

from httptools import parse_url

s = Sanic(name="test")

@s.signal("app.route.before")
async def route_before(app, loop, signal, signal_data: SignalData):
    # Having some event generation before the route resolution can help you automatically route your request to a different URL in case of deprecation/Removal of Old APIs
    signal_data.request._parsed_url = parse_url(b"/tests")
    print(f"Route Event {signal_data}")

@s.signal("app.route.missing")
async def invalid_route_event(app, loop, signal, signal_data):
    print(f"Missing {signal_data}")

@s.signal(signal="foo.bar.baz")
async def event_handler(app, loop, signal, signal_data):
    print(f"Signal Received with {signal_data}")

@s.signal(signal="foo.bar.baz")
async def event_handler1(app, loop, signal, signal_data):
    print("Signal Received1 ")

@s.signal(signal="foo.bar.baz")
async def event_handler2(app, loop, signal, signal_data):
    print("Signal Received2")

@s.middleware("request")
async def middleware(reques):
    print("HERE")

@s.route("/get")
async def get(request):
    await s.publish(signal="foo.bar.baz", data={"email": "[email protected]"})
    return json({"test": "test"})

s.freeze()
s.run(port=1245, debug=True)

TODO

  • Handle Existing Event Infra for listeners
  • Performance Test to make sure this doesn't add a noticeable overhead
  • Clean exception handling (Possibly indicate what signal dispatch failure can be ignored)
  • If the Signal Dispatch doesn't need to happen in a sequence, run them as async tasks ?
  • Enable Support on the middleware, blueprint and blueprint groups
  • Possible Router level events ?
  • Handle Signal freeze ?
  • Better cache support for signal registry (lru_cache)
  • Async support for Router.get might enable much better route even generation?
  • Finalise Custom Event Generation API names

@codecov
Copy link

codecov bot commented Feb 28, 2021

Codecov Report

Merging #2041 (f4e00da) into master (dbfc11f) will decrease coverage by 0.465%.
The diff coverage is 80.469%.

Impacted file tree graph

@@              Coverage Diff              @@
##            master     #2041       +/-   ##
=============================================
- Coverage   92.070%   91.605%   -0.465%     
=============================================
  Files           33        35        +2     
  Lines         3102      3228      +126     
  Branches       542       556       +14     
=============================================
+ Hits          2856      2957      +101     
- Misses         166       186       +20     
- Partials        80        85        +5     
Impacted Files Coverage Δ
sanic/mixins/signals.py 51.724% <51.724%> (ø)
sanic/app.py 91.667% <75.000%> (-0.298%) ⬇️
sanic/signals.py 87.500% <87.500%> (ø)
sanic/__init__.py 100.000% <100.000%> (ø)
sanic/base.py 100.000% <100.000%> (ø)
sanic/exceptions.py 100.000% <100.000%> (ø)
sanic/router.py 92.405% <100.000%> (+0.300%) ⬆️
sanic/utils.py 80.952% <100.000%> (+7.619%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update dbfc11f...f4e00da. Read the comment docs.

sanic/mixins/signals.py Outdated Show resolved Hide resolved
def signal(self, signal: str):
def _wrapper(handler: t.Callable):
parts = signal.split(".")
if len(parts) < 2 or len(parts) > 3:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be we can avoid checking and raise an Index error and be done with it?

sanic/signals.py Show resolved Hide resolved
@ahopkins
Copy link
Member

I have a branch that implements this using the new router. Some slight changes in API design, but I think a similar approach. I will push the branch for you to look at and take a closer look at this PR later. Ping me on the DIscord server, it might be nice to find a chance to hash out some details in realtime.

@ahopkins
Copy link
Member

See signals-api

Copy link
Member

@ahopkins ahopkins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to discuss implementation strategy.

@ahopkins ahopkins mentioned this pull request Feb 28, 2021
@harshanarayana
Copy link
Contributor Author

Closing in favor of /pull/2042

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants