-
Notifications
You must be signed in to change notification settings - Fork 89
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
Add support for running optimized native code for websocket mask #394
Conversation
d64ea32
to
e914862
Compare
12d7cc5
to
8dc344f
Compare
What do you need from me here @alisinabh? Is this ready to be merged? |
It is not ready to be merged at this point. I think we should discuss which approach we want to take (a bandit_native lib vs a compile time configurable module name) and then go forward. What do you think? |
I vote for this to be configurable |
e914862
to
b63377c
Compare
bandit_native
supportb63377c
to
5dfa2dd
Compare
5dfa2dd
to
8dc4348
Compare
@mtrudel This is now ready for a review. I have also updated https://github.com/alisinabh/bandit_native if you want to give it a test. |
lib/bandit/extractor.ex
Outdated
|
||
@spec new(module(), Keyword.t()) :: t() | ||
def new(frame_parser, opts) do | ||
max_frame_size = Keyword.get(opts, :max_frame_size, 0) | ||
primitive_ops_module = Keyword.get(opts, :primitive_ops_module) || Bandit.PrimitiveOps.Default |
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.
primitive_ops_module = Keyword.get(opts, :primitive_ops_module) || Bandit.PrimitiveOps.Default | |
primitive_ops_module = Keyword.get(opts, :primitive_ops_module, Bandit.PrimitiveOps.Default) |
A couple of things:
|
Sorry this is my bad. Will move it there.
I personally prefer one module for now as it makes configuration easier. But no strong opinions from me. On another note, I was wondering if we should move this configuration outside of protocols config and make it a bandit level configuration like below. I think other than benchmarking reasons, it does not make sense to have two bandit instances running with different primitive ops implementations in the same application. (Not sure if we discussed this before) config :bandit, primitive_ops_module: MyCustomModule
# or
config :bandit, websoket_primitive_ops_module: MyCustomModule |
I think I prefer having a module per protocol, as it makes what you're working on clearer. If they happen to resolve to identical native modules that's fine, but the mapping from Bandit-land to native-land should probably be done on a per-protocol basis. I don't hold that too strongly though. In either case, we should mark the config points as experimental and subject to change. |
@mtrudel Agreed. I have updated this PR accordingly. We now have |
lib/bandit/extractor.ex
Outdated
|
||
@spec new(module(), Keyword.t()) :: t() | ||
def new(frame_parser, opts) do | ||
max_frame_size = Keyword.get(opts, :max_frame_size, 0) | ||
primitive_ops_module = Keyword.fetch!(opts, :primitive_ops_module) |
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.
Rather than the put_new
elsewhere, is there a reason not to use Keyword.get
with a default of Bandit.PrimitiveOps.WebSocket
here?
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.
I thought we don't want to couple the Extractor module with websocket specifics (even though it is only used for websockets as of now).
But we can either do a Keyword.get/3
as you suggested or add an argument to the new/3 so it looks like def new(frame_parser, primitive_ops_module, opts)
. LMK what you prefer.
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.
Good point about extractor reuse!
It's a required thing, so I think a separate arg to new/3 makes the most sense
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.
Updated in 028e890. Also do you think I should drop _module
suffix from primitive_ops_module
? 🤔
Looks great! |
@alisinabh out of curiosity, do you benchmarking results to share for bandit_native? |
@gmile I have the following benchmark but I wouldn't say it is a good one.
|
This PR adds optional support for native implementation of some functions for bandit.
Some functions like websocket masking, and UTF8 validation can use more efficient native implementations which can speed up bandit in specific use-cases.
Other options
Instead of relying on
bandit_native
package, this can also be a compile config + a behaviour like this:Update
Instead of relying on a single
bandit_native
library, this PR switched to using a configuration based approach using a behaviour for so calledPrimitiveOps
.