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

Declarative configuration #36

Open
singulared opened this issue Nov 29, 2021 · 5 comments
Open

Declarative configuration #36

singulared opened this issue Nov 29, 2021 · 5 comments
Assignees
Labels
configuration daemon Hitboxd related issues enhancement New feature or request research
Milestone

Comments

@singulared
Copy link
Member

singulared commented Nov 29, 2021

The main idea of this task is to add some mechanism that implements the ability to declaratively describe the hitbox configuration.

  • HTTP server configuration (host, port, etc.)
  • Backend configuration (ideally we can use multiple backends at the same time for some endpoint aka L1, L2 caches)

Main configuration entities:

  • Endpoint (Some atomic cache configuration block identified by HTTP path, method or something else)
  • Upstream (Application or multiple application instances that we want to wrap with a cache)
  • Group (Group of Endpoints with the same configuration) (I think groups don't need in MVP)

Configuration manager should own configuration state and should have the ability to reload it on runtime.

Basic example of config file (discussable)

inbound:
  proto: HTTP
  port: 8080
  host: 0.0.0.0

backends:
  - redis:
      proto: redis
      host: 127.0.0.1
      port: 6379
      database: 0

upstreams:
  google:
    host: 8.8.8.8
    port: 8080

endpoints:
  index:
    upstream: "google"
    backends:
      - redis
    matchers:
      - matcher:
          path: "/index/"
      - matcher:
          method: GET
@singulared singulared added the enhancement New feature or request label Nov 29, 2021
@AndreyErmilov
Copy link
Contributor

AndreyErmilov commented Nov 29, 2021

For the https://api.github.com/repos/vmg/redcarpet/issues?state=closed

inbound:
  proto: HTTP
  port: 8080
  host: 0.0.0.0

backends:
  - redis:
      proto: redis
      host: 127.0.0.1
      port: 6379
      database: 0

upstreams:
  google:
    host: 8.8.8.8
    port: 8080
    endpoints:
      index:
        backends:
          - redis
        matchers:
          - matcher:
              path: "/index/"
          - matcher:
              method: GET
  github:
    host: api.github.com
    port: 80
    endpoints:
      issues:
        backends:
          - redis
        matchers:
          - matcher:
              path: "/repos/{user:string}/{repo:string}/issues/"
              method: GET
        keys:
          query:
            - type: enum
              name: state
              values:
                - closed
                - open

@AndreyErmilov
Copy link
Contributor

AndreyErmilov commented Nov 29, 2021

About Settings

It seems that we need to separate two layers from each other. The first layer is the structures which are the internal representation of the hitbox-server settings. The second layer is the user configuration (yaml etc.). The layer with the user configuration is converted into the first layer, the internal representation of the settings.
Both the first and second layers solve the same task, but each layer has its own specifics.

  1. First of all, we don't want to use the internal structures of the hitbox server because we don't want to know about them. And we don't want to change everything if we need to change the internal structures of the hitbox server.
  2. The second reason is that user configuration should be as simple as possible. We add groups, etc. to automate and reduce copying.

Internal HitboxServer state

struct Hitbox

  • host, port
  • protocol (HTTP/S, gRPC)

struct UpstreamSettings

  • name
  • host, port
  • protocol (HTTP/S, gRPC)
  • backend
  • endpoints
    • name
    • backend
    • matchers for request
    • matchers for response
    • cache key

struct Backend

  • name
  • host, port
  • database

Couple lines of code

trait Backend {}

trait Matcher<T> {
    fn apply(&self, source: T) -> bool;
}

trait KeyExtractor<T> {
    fn extract(&self, source: T) -> String;
}

trait Request {}
trait Response {}

impl Request for HTTPRequest {

}

impl Request for GRPC {

}

struct Endpoint<Request, Response>
where
    Request: Request,
    Response: Response,
{
    name: String,
    backend: Vec<Box<dyn Backend>>,
    request: Vec<Box<dyn Matcher<Request>>>,
    response: Vec<Box<dyn Matcher<Response>>>,
    cache_key: Vec<Box<dyn KeyExtractor<Request>>>,
}

impl<Request, Response> Endpoint<Request, Response>
where
    Request: Request,
    Response: Response,
{

}

@AndreyErmilov
Copy link
Contributor

AndreyErmilov commented Dec 1, 2021

TBD:
@singulared

# hitbox server base settings
server:
  host: 127.0.0.1
  port: 8080
  proto: HTTP

# map of applications
upstreams:
  api:
    host: 127.0.0.1
    port: 8080
    proto: HTTP

# map of backends
backends:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0
  inmemory:
    max_size: 1Gb

# map of cache policies
policies:
  cache_with_lock:
    cache: enabled
    lock: local
    stale: disabled
  non_cacheable:
    cache: disabled

# default settings
cache:
  ttl: 1min
  prefix: api
  version: 1
  backend: redis
  policies: cache_with_lock

# map of groups
groups:
  api:
    upstream: api
  sitemaps:
    upstream: api
    backend: inmemory
  exclude:
    upstream: api
    policy: non_cacheable

# list of all endpoint
endpoints:
  - path: "/clusters/{cluster_id:i32}/comments/"
    request:
      query:
        page:
          type: i32
        sort_by:
          type: enum
          variants:
            - date
            - clicks
      headers:
        x-source:
          type: enum
          variants:
            - ios
    response:
      headers:
        content-type: application/json
      status: 200
      if: "cluster.items"
    group: api
  - path: "/cluster/{cluster_id:i32}/"
    group: api
  - path: "/sitemaps/"
    group: sitemaps

@AndreyErmilov AndreyErmilov self-assigned this Dec 4, 2021
@singulared singulared added this to the hitbox-server 0.1.0 (MVP) milestone Dec 4, 2021
@singulared
Copy link
Member Author

@AndreyErmilov As I said in #38 we cat interpret all params as strings as I think. This will lead to some simplification of the configuration scheme.

@singulared singulared added the daemon Hitboxd related issues label Jul 5, 2023
@singulared singulared removed this from the hitbox-server 0.1.0 (MVP) milestone Jul 5, 2023
@singulared singulared assigned EveIsSim and unassigned AndreyErmilov Jul 5, 2023
@singulared
Copy link
Member Author

@singulared singulared added this to the hitboxd-alpha milestone Jul 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
configuration daemon Hitboxd related issues enhancement New feature or request research
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants