-
Notifications
You must be signed in to change notification settings - Fork 98
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
Design and Implementation of Filters #1
Comments
Coming up with a filter configuration that works for both client and server configuration. This is what I came up with:
For example: client-proxy.yaml local:
port: 7000 # the port to receive traffic to locally
filters: # new filters section
- name: "quilkin.core.v1.rate-limiter" # the name that this filter is registered under
config:
map: of arbitrary key value pairs
could:
- also
- be
- an
- array
client:
address: 127.0.0.1:7001 # the address to send traffic to
connection_id: 1x7ijy6 # the connection string to attach to the traffic server-proxy.yaml local:
port: 7001 # the port to receive traffic to locally
filters:
- name: "quilkin.core.v1.rate-limiter" # the name that this filter is registered under
config:
map: of arbitrary key value pairs
could: 42
server:
endpoints: # array of potential endpoints to send on traffic to
- name: Game Server No. 1
address: 127.0.0.1:26000
connection_ids:
- 1x7ijy6 # connection ids to route on
- 8gj3v2i
- name: Game Server No. 2
address: 127.0.0.1:26001
connection_ids:
- nkuy70x How do we feel about a setup like this? |
I'd prefer it if the client could get as much config as possible from the server rather than having its own, does that make sense ? It avoids people modifying the client config file in a way we don't want them to, and also makes it easier for us to update. |
So you raise an interesting idea @luna-duclos ! So in my mind, the yaml file is a useful data structure design tool / stopgap / during game development tool util we have a gRPC control API (#10) down the line -- which would let you configure everything we can see in the yaml file (which is basically how Envoy works - you have a static config, i.e. yaml and a dynamic config, i.e. via the API) So in production, the client would likely make a gRPC connection to the proxy to configure it - meaning there is far less surface area for a user to manipulate (especially easily on the client side). Then it would be the responsibility of the custom client/game system to receive and propagate out any configuration updates as required. In my mind - Quilkin doesn't provide the control plane, but provides the foundation for a control plane (much like the difference between Envoy and Istio). We could then down the line have separate opinionated control plane implementations on top of Quilkin. That all being said, we should think about how we can ensure the client side proxy is relatively tamper proof - or at least, if people DO tamper with it, it doesn't really affect anything. (maybe part we have a filter for quilkin that sends a hash of the current config, and the server receives the hash, and if it's changed, it refuses the connection???) - but this feels to me like a separate design ticket. Also, depending on how we do the gRPC control plane API (which I think comes once we've locked down the design of some of the basic config data structures), what you propose might actually be possible -- depending on how you set it up. (i.e. should the control plane reach out to something? Should it be only accept connections? maybe both? but that's a discussion for #10) That sound good? |
Had an offline slack chat. We agreed that this is an appropriate data structure for filters at this stage. |
Not sure why I decided to have that function return a HashMap, but to implement filters, we need access to the underlying Endpoints, since they get passed into several Filter functions. So refactored the function to return a Vec<Endpoint>, which will make things much easier to work with. Work on #1
Not sure why I decided to have that function return a HashMap, but to implement filters, we need access to the underlying Endpoints, since they get passed into several Filter functions. So refactored the function to return a Vec<Endpoint>, which will make things much easier to work with. Work on #1
Since packets might not come back from the endpoint address that we expect it to, we should track this data in our filter. Now we can! Work on #1
Since packets might not come back from the endpoint address that we expect it to, we should track this data in our filter. Now we can! Work on #1
Since packets might not come back from the endpoint address that we expect it to, we should track this data in our filter. Now we can! Work on #1
FilterChain for local_receive_filter is in place, and working as expected, with accompanying unit tests. Found a small issue in Session as well that also got fixed in this PR that came up in the unit tests. Work on #1
FilterChain for local_receive_filter is in place, and working as expected, with accompanying unit tests. Found a small issue in Session as well that also got fixed in this PR that came up in the unit tests. Work on #1
FilterChain for local_receive_filter is in place, and working as expected, with accompanying unit tests. Found a small issue in Session as well that also got fixed in this PR that came up in the unit tests. Work on #1
Implementation plus unit tests! Work on #1
* Implementation of local_send_filter Implementation plus unit tests! Work on #1
This includes passing the FilterChain into the Session, so that is can call endpoint_send_filter when sending data out through the endpoint. Work on #1
* Implementation of endpoint_send_filter This includes passing the FilterChain into the Session, so that is can call endpoint_send_filter when sending data out through the endpoint. Work on #1
This includes a unit test to cover the full set of filters. Next step - more integration tests! Work on #1
Next step - more integration tests! Work on #1
Better testing, now we have more filters implemented. Work on #1
Next step - more integration tests! Work on #1
Better testing, now we have more filters implemented. Work on #1
From conversation today, we need to look at the filter ordering is reversed appropriately between sending and recieving, so that filters run in the correct order. For example, we may need to flip ordering around here on endpoint receive: |
End to end test of the TestFilter implementation, proving an integration test for the full Filter trait experience. Work on #1
End to end test of the TestFilter implementation, proving an integration test for the full Filter trait experience. Work on #1
This PR implements lazy instantiation of filters through a closure - which also leads to the ability to pass the server_yaml::Value for the config of the filter, which was a nice side effect. To prove the lazy eval and config passing was working, this also added the ability to pass an "id" value to the DebugFilter, such that you could implement several of them in a Filter configuration in between other filters, and be able to identify which log statement is which step. This also led to finding multiple places in which an Arc was being used, but only the guarantees of a Box where actually needed, so this was also switched out. An integration test for the DebugFilter is still incoming. Work on #1
This PR implements lazy instantiation of filters through a closure - which also leads to the ability to pass the server_yaml::Value for the config of the filter, which was a nice side effect. To prove the lazy eval and config passing was working, this also added the ability to pass an "id" value to the DebugFilter, such that you could implement several of them in a Filter configuration in between other filters, and be able to identify which log statement is which step. This also led to finding multiple places in which an Arc was being used, but only the guarantees of a Box where actually needed, so this was also switched out. An integration test for the DebugFilter is still incoming. Work on #1
This PR implements lazy instantiation of filters through a closure - which also leads to the ability to pass the server_yaml::Value for the config of the filter, which was a nice side effect. To prove the lazy eval and config passing was working, this also added the ability to pass an "id" value to the DebugFilter, such that you could implement several of them in a Filter configuration in between other filters, and be able to identify which log statement is which step. This also led to finding multiple places in which an Arc was being used, but only the guarantees of a Box where actually needed, so this was also switched out. An integration test for the DebugFilter is still incoming. Work on #1
This PR implements lazy instantiation of filters through a closure - which also leads to the ability to pass the server_yaml::Value for the config of the filter, which was a nice side effect. To prove the lazy eval and config passing was working, this also added the ability to pass an "id" value to the DebugFilter, such that you could implement several of them in a Filter configuration in between other filters, and be able to identify which log statement is which step. This also led to finding multiple places in which an Arc was being used, but only the guarantees of a Box where actually needed, so this was also switched out. An integration test for the DebugFilter is still incoming. Work on #1
* Lazy instantiation of Filters This PR implements lazy instantiation of filters through a closure - which also leads to the ability to pass the server_yaml::Value for the config of the filter, which was a nice side effect. To prove the lazy eval and config passing was working, this also added the ability to pass an "id" value to the DebugFilter, such that you could implement several of them in a Filter configuration in between other filters, and be able to identify which log statement is which step. This also led to finding multiple places in which an Arc was being used, but only the guarantees of a Box where actually needed, so this was also switched out. An integration test for the DebugFilter is still incoming. Work on #1 * FilterProvider implementation. * Switch to FilterProvider being instantiatable. * Implement from_config() returning Result * Move log into Provider. * Refactor Provider -> Factory
Some filters will need to be aware of whether they are client/server, and also authentication connection details. To provide this functionality, this PR added ConnectionConfig to the CreateFilterArgs, so it can be passed into FilterFactory's when needed. Work on #1
* Added ConnectionConfig to CreateFilterArgs Some filters will need to be aware of whether they are client/server, and also authentication connection details. To provide this functionality, this PR added ConnectionConfig to the CreateFilterArgs, so it can be passed into FilterFactory's when needed. Work on #1 * Updates based on review.
This implements that the FilterChain executes the set of Filters in a forward order on read, and then in reverse order on write. Also provides an integration test to confirm that the ordering is working as expected. Closes #1
This implements that the FilterChain executes the set of Filters in a forward order on read, and then in reverse order on write. Also provides an integration test to confirm that the ordering is working as expected. Closes #1
Need to come up with a design for filters, and then implement it!
The text was updated successfully, but these errors were encountered: