flagr

package module
v0.0.0-...-ab1e18c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2023 License: MIT Imports: 14 Imported by: 0

README

flagr

A Caddy v2 extension to apply Feature Flags for HTTP requests by using Flagr.

Installation

$ xcaddy build --with github.com/RussellLuo/caddy-ext/flagr

Caddyfile Syntax

flagr <url> {
    evaluator <evaluator> [<refresh_interval>]
    entity_id <entity_id>
    entity_context {
        <key1>    <value1>
        <key2>    <value2>
        ...
    }
    flag_keys <key1> <key2> ...
    bind_variant_keys_to <bind_variant_keys_to>
}

Parameters:

  • <url>: The address of the Flagr server.
  • <evaluator>: Which evaluator to use. Defaults to "local". Supported options:
    • "local"
    • "remote"
  • <refresh_interval>: The refresh interval of the internal eval cache (only used for the "local" evaluator). Defaults to "10s".
  • <entity_id>: The unique ID from the entity, which is used to deterministically at random to evaluate the flag result. Defaults to "" (Flagr will randomly generate one), and it must be a Caddy variable if provided:
    • {path.<var>}
    • {query.<var>}
    • {header.<VAR>}
    • {cookie.<var>}
    • {body.<var>} (requires the requestbodyvar extension)
  • <entity_context>: The context parameters (key-value pairs) of the entity, which is used to match the constraints. The value part may be a Caddy variable (see <entity_id>).
  • <flag_keys>: A list of flag keys to look up.
  • <bind_variant_keys_to>: Which element of the request to bind the evaluated variant keys. Defaults to "header.X-Flagr-Variant". Supported options:
    • "header.<VAR>"
    • "query.<var>"

Example

With the Flagr config and the Caddyfile as below:

flagr-config

localhost:8080 {
    route /foo {
        flagr http://127.0.0.1:18000/api/v1 {
            entity_id {query.id}
            entity_context {
              city CD
            }
            flag_keys demo
        }
        respond {header.X-Flagr-Variant} 200
    }
    route /bar {
        flagr http://127.0.0.1:18000/api/v1 {
            entity_id {query.id}
            entity_context {
              city BJ
            }
            flag_keys demo
        }
        respond {header.X-Flagr-Variant} 200
    }
}

You can get the responses as follows:

$ curl 'https://localhost:8080/foo?id=1'
demo.on
$ curl 'https://localhost:8080/bar?id=1'

Local Evaluator vs Remote Evaluator

Internals

local-vs-remote

Benchmarks

Prerequisites:

  • Run Flagr locally with docker

  • Use the same Flagr config as in Example

  • Run Caddy with the following Caddyfile:

    localhost:8080 {
        route /local {
            flagr http://127.0.0.1:18000/api/v1 {
                evaluator local
                entity_id {query.id}
                entity_context {
                  city CD
                }
                flag_keys demo
            }
            respond 204
        }
        route /remote {
            flagr http://127.0.0.1:18000/api/v1 {
                evaluator remote
                entity_id {query.id}
                entity_context {
                  city CD
                }
                flag_keys demo
            }
            respond 204
        }
    }
    
  • Install the benchmarking tool wrk

Here are the benchmark results I got on my MacBook:

$ wrk -t15 -c200 -d30s 'https://localhost:8080/local?id=1'
Running 30s test @ https://localhost:8080/local?id=1
  15 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.14ms    8.83ms 161.49ms   90.13%
    Req/Sec     2.48k   396.11     8.44k    80.79%
  1106860 requests in 30.10s, 83.39MB read
Requests/sec:  36769.32
Transfer/sec:      2.77MB
$ wrk -t15 -c200 -d30s 'https://localhost:8080/remote?id=1'
Running 30s test @ https://localhost:8080/remote?id=1
  15 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    48.68ms   97.87ms   1.20s    89.98%
    Req/Sec   778.59    239.79     1.66k    71.50%
  348077 requests in 30.10s, 26.22MB read
Requests/sec:  11564.13
Transfer/sec:      0.87MB

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddConverter

func AddConverter(n string, c Converter) error

Types

type ContextValue

type ContextValue struct {
	Value      interface{}
	IsCaddyVar bool
	Converters []Converter `json:"-"`
}

type Converter

type Converter func(string) (interface{}, error)

func GetConverter

func GetConverter(n string) (Converter, error)

type Evaluator

type Evaluator interface {
	PostEvaluationBatch(ctx context.Context, req *models.EvaluationBatchRequest) (*models.EvaluationBatchResponse, error)
}

type Flagr

type Flagr struct {
	// The address of the flagr server.
	URL string `json:"url,omitempty"`

	// Which evaluator to use.
	// Supported options: "local" or "remote".
	Evaluator string `json:"evaluator,omitempty"`
	// The refresh interval of the internal eval cache (only used for the "local" evaluator).
	RefreshInterval string `json:"refresh_interval,omitempty"`

	// The unique ID from the entity, which is used to deterministically at
	// random to evaluate the flag result. Must be a Caddy variable.
	EntityID string `json:"entity_id,omitempty"`

	// The context parameters (key-value pairs) from the entity, which is used
	// to match the constraints.
	EntityContext map[string]interface{} `json:"entity_context,omitempty"`

	// A list of flag keys to look up.
	FlagKeys []string `json:"flag_keys,omitempty"`

	// Which element of the request to bind the evaluated variant keys.
	// Supported options: "header.NAME" or "query.NAME".
	BindVariantKeysTo string `json:"bind_variant_keys_to,omitempty"`
	// contains filtered or unexported fields
}

Flagr implements a handler for applying Feature Flags for HTTP requests by using checkr/flagr.

func (Flagr) CaddyModule

func (Flagr) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*Flagr) Cleanup

func (f *Flagr) Cleanup() error

Cleanup cleans up the resources made by rl during provisioning.

func (*Flagr) Provision

func (f *Flagr) Provision(ctx caddy.Context) (err error)

Provision implements caddy.Provisioner.

func (*Flagr) ServeHTTP

func (f *Flagr) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

ServeHTTP implements caddyhttp.MiddlewareHandler.

func (*Flagr) UnmarshalCaddyfile

func (f *Flagr) UnmarshalCaddyfile(d *caddyfile.Dispenser) (err error)

UnmarshalCaddyfile implements caddyfile.Unmarshaler. Syntax:

flagr <url> {
    evaluator <evaluator> [<refresh_interval>]
    entity_id <entity_id>
    entity_context {
        <key1>    <value1>
        <key2>    <value2>
        ...
    }
    flag_keys <key1> <key2> ...
    bind_variant_keys_to <bind_variant_keys_to>
}

func (*Flagr) Validate

func (f *Flagr) Validate() error

Validate implements caddy.Validator.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL