Code Monkey home page Code Monkey logo

fluxninja / aperture Goto Github PK

View Code? Open in Web Editor NEW
590.0 6.0 21.0 207.47 MB

Rate limiting, caching, and request prioritization for modern workloads

Home Page: https://docs.fluxninja.com

License: Apache License 2.0

Makefile 0.25% Shell 0.87% Dockerfile 0.23% Go 50.98% Smarty 0.51% Starlark 1.00% Jsonnet 5.68% JavaScript 3.29% Python 2.47% Java 4.24% Lua 0.17% TypeScript 2.26% HTML 20.96% C# 6.69% CSS 0.38%
kubernetes rate-limiter cloud-native microservices observability scheduler caching concurrency-limiter llm

aperture's Introduction

FluxNinja Aperture
Documentation Reference Slack Community Build Status Go Report Card Godoc Reference

๐Ÿฅท FluxNinja Aperture

Aperture is a distributed load management platform designed for rate limiting, caching, and prioritizing requests in cloud applications. Built upon a foundation of distributed counters, observability, and a global control plane, it provides a comprehensive suite of load management capabilities. These capabilities enhance the reliability and performance of cloud applications, while also optimizing cost and resource utilization.

Unified Load Management Unified Load Management

Integrating Aperture in your application through SDKs is a simple 3-step process:

  • Define labels: Define labels to identify users, entities, or features within your application. For example, you can define labels to identify individual users, features, or API endpoints.
Example
// Tailor policies to get deeper insights into your workload with labels that
// capture business context.
const labels = {
  // You can rate limit each user individually.
  user: "jack",
  // And have different rate limits for different tiers of users.
  tier: "premium",
  // You can also provide the tokens for each request.
  // Tokens are flexible: LLM AI tokens in a prompt, complexity of a request,
  // number of sub-actions, etc.
  tokens: "200",
  // When peak load exceeds external quotas or infrastructure capacity,
  // requests can be throttled and prioritized.
  priority: HIGH,
  // Get deep insights into your workload. You can slice and dice performance
  // metrics by any label.
  workload: "/chat",
};
  • Wrap your workload: Wrap your workload with startFlow and endFlow calls to establish control points around specific features or code sections inside your application. For example, you can wrap your API endpoints with Aperture SDKs to limit the number of requests per user or feature.
Example
// Wrap your workload with startFlow and endFlow calls, passing in the
// labels you defined earlier.
const flow = await apertureClient.startFlow("your_workload", {
  labels: labels,
  // Lookup result cache key to retrieve a cached result.
  resultCacheKey: queryParams,
});

// If rate or quota limit is not exceeded, the workload is executed.
if (flow.shouldRun()) {
  // Return a cached result or execute the workload.
  const cachedResult = flow.resultCache();
  const result = await yourWorkload(cachedResult);
  flow.setResultCache({
    value: result,
    ttl: { seconds: 86400, nanos: 0 },
  });
}
//
  • Configure & monitor policies: Configure policies to control the rate, concurrency, and priority of requests.
Policy YAML
blueprint: rate-limiting/base
uri: github.com/fluxninja/aperture/blueprints@latest
policy:
  policy_name: rate_limit
  rate_limiter:
    bucket_capacity: 60
    fill_amount: 60
    parameters:
      interval: 3600s
      limit_by_label_key: user
    selectors:
      - control_point: your_workload
        label_matcher:
          match_list:
            - key: tier
              operator: In
              values:
                - premium

Rate Limiter Blueprint Rate Limiter Blueprint Rate Limiter Dashboard Rate Limiter Dashboard

In addition to language SDKs, Aperture also integrates with existing control points such as API gateways, service meshes, and application middlewares.

โš™๏ธ Load management capabilities

  • โฑ๏ธ Global Rate and Concurrency Limiting: Safeguard APIs and features against excessive usage with Aperture's high-performance, distributed rate limiter. Identify individual users or entities by fine-grained labels. Create precise rate limiters controlling burst-capacity and fill-rate tailored to business-specific labels. Limit per user or global concurrency of in-flight requests. Refer to the Rate Limiting and Concurrency Limiting guides for more details.
  • ๐Ÿ“Š API Quota Management: Maintain compliance with external API quotas with a global token bucket and smart request queuing. This feature regulates requests aimed at external services, ensuring that the usage remains within prescribed rate limits and avoids penalties or additional costs. Refer to the API Quota Management guide for more details.
  • ๐Ÿšฆ Concurrency Control and Prioritization: Safeguard against abrupt service overloads by limiting the number of concurrent in-flight requests. Any requests beyond this limit are queued and let in based on their priority as capacity becomes available. Refer to the Concurrency Control and Prioritization guide for more details.
  • ๐ŸŽฏ Workload Prioritization: Safeguard crucial user experience pathways and ensure prioritized access to external APIs by strategically prioritizing workloads. With weighted fair queuing, Aperture aligns resource distribution with business value and urgency of requests. Workload prioritization applies to API Quota Management and Concurrency Control and Prioritization use cases.
  • ๐Ÿ’พ Caching: Boost application performance and reduce costs by caching costly operations, preventing duplicate requests to pay-per-use services, and easing the load on constrained services. Refer to the Caching guide for more details.

๐Ÿ Getting Started

โ˜๏ธ Aperture Cloud

Note

FluxNinja has been acquired by CodeRabbit. New sign-ups are temporarily disabled. Existing users can continue to use Aperture Cloud by signing in to their accounts.

The easiest way to try Aperture is to sign up for a free Aperture Cloud account. Aperture Cloud is a fully managed service by FluxNinja. With Aperture Cloud, there's no need to manage any infrastructure, and you can integrate your application with Aperture using SDKs. For more information, refer to the get started guide.

Quota Management Dashboard Quota Management Dashboard Prioritization Metrics for gpt-4 Flow Analytics Flow Analytics Performance Metrics for OpenAI Models

๐ŸŽฎ Local Kubernetes Playground

To try Aperture in a local Kubernetes environment, refer to Playground docs.

๐Ÿ“– Learn More

๐ŸŽฅ Videos

๐Ÿ‘ท Contributing

Reporting bugs helps us improve Aperture to be more reliable and user-friendly. Include all the required information to reproduce and understand the bug you are reporting. Follow helper questions in the bug report template to make it easier. If you see a way to improve Aperture, use the feature request template to create an issue.

To contribute code, read the Contribution guide.

aperture's People

Contributors

chiukapoor avatar code-shreyas avatar dariakunoichi avatar dependabot[bot] avatar fluxninjaops avatar fossabot avatar gitcommitshow avatar github-actions[bot] avatar gurinder39 avatar harjotgill avatar hasit avatar hdkshingala avatar imgbot[bot] avatar iridiumoxide avatar jaidesai-fn avatar jmichalak-fluxninja avatar karansohi avatar kklimonda-fn avatar krdln avatar kwapik avatar ninjacharu avatar sadovnikov avatar sahil-lakhwani avatar sbienkow-ninja avatar seunghyupoh3517 avatar slayer321 avatar spikatrix avatar sudhanshu456 avatar tanveergill avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

aperture's Issues

Update telemetry schema with workloads

The goal of this ticket is to update the data format which we're sending in logs and traces.

To do that the following changes should be applies to the metricsprocessor:

  1. Add workloads and dropping_workloads attributes with format:
    policy_name:<policy_name>,component_index:<component_index>,workload_index:<workload_index>,policy_hash:<policy_hash>
    
  2. Change concurrency_limiters and dropping_concurrecy_limiters format to:
    policy_name:<policy_name>,component_index:<component_index>,policy_hash:<policy_hash>
    
  3. Change flux_meters format to:
    <flux_meter_name>
    
  4. Add classifiers attribute with format (depends on #268):
    policy_name:<policy_name>,classifier_index:<classifier_index>
    

Useful links:

  1. Function in metricsprocessor which needs to be changed

Remove Istio from chart dependency

We don't want to provide Istio and Envoy Filter as chart dependencies and will be assuming that it would be already present on user's infrastructure or they'll do the installation on their own.

Use enums in place of strings for fields with pre-set values in Policy spec

Describe the solution you'd like

  • The change applies to following fieds:
  • Use formal protobuf enums instead of strings. The last time I tried, Buf was imposing unreasonable restrictions e.g. first field needs to be unspecified and all fields need to begin with the same prefix etc. See if we can get around these constraints in Buf.
  • Make sure the user facing spec is similar, in the sense that they still specify a human readable string in the YAML as the operator.

Describe alternatives you've considered

  • Retain string based fields. If the enum path is un-tractable for whatever reason we can stay with the string based approach.

Additional context

  • The YAML spec still should not be too off from what's present currently
  • This change simplifies the unmarshal code.
  • Easier to document enum fields than string values
  • Validation is built-in

Please delete paragraphs that you did not use before submitting.

A new multi-value column in Druid to capture all FlowLabelKeys

Describe the solution you'd like

  • Put matched FlowLabelKeys in flowcontrolv1.CheckResponse
  • Make sure the FlowLableKeys propagate to Envoy logs and SDK traces via AuthAPI dynamic metadata and trace header respectively
  • OTEL metrics processing pipeline reads FlowLabelKeys from logs and traces and adds a multi-value field flow_label_keys in Druid events. Refer how other multi-value fields such as flux_meters get populated.

Rationale

  • Users need feedback to create Selector. It's hard to write one without knowing labels are available. Exposing flow_label_keys in Druid is a quick and effective way to achieve that.

Send agent key as label on sentry events

  • Send agent key as a label on sentry events

  • Sentry plugin needs to subscribe to agent key from FN Cloud plugin via Fx

  • Refactor of Crashwriter included: Keep raw zerolog events in the CrashWriter circular buffer and only do the sentry parsing when panic happens
    (i.e. Convert zerolog to sentry only when it's ready to send those logs to sentry to reduce the unnecessary processing)

Refer all metric names and labels from pkg/metrics/schema.go

Is your feature request related to a problem? Please describe.

  • There is repetition of metric names, labels in the codebase which is hard to maintain.

Describe the solution you'd like

  • Strings for metrics, labels key and label values can be defined in a common file shared by both agent and controller under pkg/metrics/schema.go
  • The advantages of this approach:
    • Fewer chances of errors via typos
    • Changing metric names and labels is as easy as changing it one place
    • Possible to map dependencies of a metric/label via LSPs and code indexers like ctags

Additional context

Refactor status package

  • Optimize status registry for writing instead of reading
    This change will get rid of flat maps that were being maintained on every write.

  • Create a new registry updater object when NewRegistry is called, making each object hold its own tree

Update README.md

The goal of this issue is to fill README.md file with all the needed information, i.e.:

  • What is aperture?
  • Resources - docs, SDKs etc.
  • Public roadmap
  • How to report issue
  • How to contribute
  • Slack community link

Some examples from autogenerated markdown files are not valid

Some of the example code from our autogenerated markdown files seem broken:

Example:

````yaml
selectoโ€ฆ
* [v1ControlPoint](#v1-control-point) โ€“ Identifies control point within a service that the rule or policy should apply tโ€ฆ

there is even some embedded HTLM code later in the same code block.

Or this one:

Example:

```yaml
Example of Declarative JSON extractor:

Improve buttons we use within Tilt

Add some extra buttons to make tilt interactions more enjoyable:

  • Button to stop the traffic (as it is running the scenario continuously by default).
  • Button to start the traffic.
  • Button to remove the default policy (as it's loaded by default).
  • Button to add the default policy.
  • Button to open Grafana UI -- also see if we can open it by default when we open Tilt UI.
  • Buttons to add/remove a classification rule (though default policy is working on headers).

Use Sentry for all the crash reporting

  • Migrate crash writer into Sentry
  • Keep the buffer of last 100 Sentry events (not sending them until the Crash happens)
  • When the Crash happens pick up and make buffered sentry events, dump status registry, (service version information - what we are currently collecting in the platform onCrash) into Sentry event and send them in the large event of Crash (single Crash event is sent to Sentry)

Add tests for Notifier pkg

  • Add test for basic and prefix notifier, ran tests on default trackers
    through channels, created write events with a transform function that
    reverse the content of any given bytes

  • Add more notifiers having same id, or generating random id to check
    corner case scenarios

  • Add tests for unmarshaller notfier, retrieved keyNotifier trough Get
    function and through constructor to check fuctionality of both
    functions.

  • Run tests function creates a default tracker, starts it, add's all
    prefix notfiers, key notifiers and events, sleeps for a tiny amount of
    time so that events can be written and then matches the content of
    bytes with expected results. Lastly, it removes the prefix, key
    notifiers and events.

Doc generator reorders properties alphabetically

See eg. https://aperture-tech-docs.netlify.app/docs/development/reference/configuration/policies#v1-rule. Since rego and extractor are required (mutually exclusive) variants of rule, they should go first and optional properties should go last. Now there's a sandwich.

Or see https://aperture-tech-docs.netlify.app/docs/development/reference/configuration/policies#-v1scheduler โ€“ the first fields are auto_tokens and default_workload, which require understanding workloads first, which is the last field.

Order of properties in docs should be the same as in definition. See envoy docs. This allows to control the reading order and put more important stuff on front.

This bug was fixed some time ago (https://github.com/fluxninja/cloud/pull/4349) (before moving to github issues), but now I see it was reintroduced.

TLS configuration for K8S client

We are missing TLS client configuration for K8S client that we use for discovery. We need to take this task as a priority.

Make sure this config is exposed in the operator etc. as well.

Rename "sidecard_mode" configuration in agent to "discovery_enabled" or equivalent

Describe the bug
Agent should not be aware of deployment mode; Configuration field names should be understandable in the context of the agent itself. Thus, the "sidecar_mode" configuration field should be removed and its functionalities moved to new fields.

Steps to reproduce
Just look at the code

What did you expect to see?
Configuration with fields unrelated to deployment mode

What did you see instead?
Configuration with fields related to deployment mode

What version did you use?
ce556a3

What config did you use?

Environment

Additional context

Fix demo app testing

  1. When we run k6 in demo app testing, only one of the pods gets the traffic.
  • Hold off on the daemonset for demo app, it might mess up the k6 tuning (i.e. Need different number of VUs to saturate the app if we change replica counts)
  • Use affinity rules in k8s to make sure only one pod of deployment runs per worker (podAntiAffinity rule based on labels)
  1. When the traffic goes to all the pods, test the rate limiter in the distributed mode.

Split Agent and Controller from Aperture CRD

We need to separate the Agent and Controller from the current Aperture repo as there can be scenarios where user might want to install the agent in one cluster and controller in other.

Change FluxMeter spec to a map

Describe the solution you'd like

  • FluxMeters change from the existing list to a map where the key of the map is the FluxMeter name. Remove the explicit name parameter in FluxMeter spec.
  • Update the FluxMeter parsing code on the cloud side in a separate PR.
  • Update the Aperture Policy Jsonnet lib and Mixin recipes, cc: @fluxninja/devops

Describe alternatives you've considered

  • Retain the existing semantics of defining the FluxMeter name as an explicit field in the FluxMeter message.

Additional context

  • This will make it consistent with classification rule set.
  • User defined keys are usually defined in a map format in other projects e.g. CircleCI jobs, Kubernetes labels
  • Kubernetes has complex requirements that the label key should adhere to. Similarly, FluxMeter name needs to be a valid Prometheus metric name format. Please document this via the Proto spec.

Modify Gradient Controller to take slope parameter instead of gradient

Currently,
$$gradient = \frac{setpoint \cdot tolerance}{signal}$$

Proposal:

$$ gradient = \left(\frac{signal}{setpoint}\right)^{slope} $$

Rationale:

  • current tolerance parameter is just pre-multiplying setpoint and could be done outside using math mul component,
  • slope parameter can be used to fine-tune the "aggresiveness" / slope of the gradient,
  • current design allows only to use the gradient controller for cases where signal is positively correlated with control variable.

Migration:

  • add a mul node if $\text{tolerance} \neq 1$
  • set the slope to $-1$.

TODO

  • code
  • proto docs
  • example policies using this controller (wherever they are commited)

As discussed with @tanveergill

Incorrect request drop rate with rate limiter policy

I tried to run the rate limiter policy with different scenarios as below but the request decisions where not as expected.

  1. I used the below rate limiter policy where I changed the limit value to 100 requests/minute per user based on the user header but the drop rate is very high and very few requests got accepted.
kind: ConfigMap
metadata:
  name: flowcontrol
  namespace: aperture-system
  labels:
    aperture.tech/validate: "true"
apiVersion: v1
data:
  rate-limit-policy.yaml: |
    evaluation_interval: "0.5s"
    circuit:
      - constant:
          value: "100.0"
          out_ports:
            output:
              signal_name: "RATE_LIMIT"
      - rate_limiter:
          in_ports:
            limit:
              signal_name: "RATE_LIMIT"
          selector:
            service: "demo1-demo-app.demoapp.svc.cluster.local"
            control_point:
              traffic: "ingress"
          label_key: "request_header_user"
          limit_reset_interval: "60s"

I have used the same load-test.js using K6 available on main and tilt under demoapp1 pod.

Below is the output from Druid:
image

  1. In this scenario, I have configured the classification for demoapp using the example available on main and changed the policy as below:
kind: ConfigMap
metadata:
  name: flowcontrol
  namespace: aperture-system
  labels:
    aperture.tech/validate: "true"
apiVersion: v1
data:
  rate-limit-policy.yaml: |
    evaluation_interval: "0.5s"
    circuit:
      - constant:
          value: "100.0"
          out_ports:
            output:
              signal_name: "RATE_LIMIT"
      - rate_limiter:
          in_ports:
            limit:
              signal_name: "RATE_LIMIT"
          selector:
            service: "demo1-demo-app.demoapp.svc.cluster.local"
            control_point:
              traffic: "ingress"
          label_key: "request_header_flow_user"
          limit_reset_interval: "60s"

In this case, all the requests got accepted and none got dropped, which I feel is also not correct as I tried different values like 10, 50 etc and still it was accepting all. I tried flow_user as value for label_key and that too had same output.

Optimize CrashWriter circular buffer

Current CrashWriter's manual circular buffer using array is not garbage collector friendly - not optimized.
Take another circular buffer library which is optimized with the go garbage collector and update the crash writer.

Dot file generator for Circuits

What

  • Takes policylangv1.Policy as input
  • Invokes controlplane.CompilePolicy to compile Policy
  • Returns output to stdout in dot file format
  • Refer #179

Requests with different priorities are having same drop rate

I was running the latency-gradient policy with load test and observed that the drop rate for requests from different workload having different priorities are almost same. Below are 2 scenarios with I checked:

  1. Executed the load test with 2 users having different workload config and different priorities in policy but their drop_rate was same:
apiVersion: v1
kind: ConfigMap
metadata:
  name: classification
  namespace: aperture-system
  labels:
    aperture.tech/validate: "true"
data:
  default.classification.yaml: |
    # Example of Flow Classification rules file, showcasing using "extractors" and raw rego.

    selector:
      service: demo1-demo-app.demoapp.svc.cluster.local
      control_point: { traffic: ingress }

    rules:
      # An example rule using extractor.
      # See following RFC for list of available extractors and their syntax.
      # https://www.notion.so/YAML-classification-policies-extractors-a7f36469fdf14c1bbc79c6ba963680a5#9ae103e0c9034c4aba30228d05d91391
      ua:
        extractor:
          from: request.http.headers.user-agent

      # The same rule using raw rego. Requires specifying rego source code and a query
      also-ua:
        rego:
          source: |
            package my.rego.pkg
            import input.attributes.request.http
            ua = http.headers["user-agent"]
          query: data.my.rego.pkg.ua

      user:
        extractor:
          from: request.http.headers.user
kind: ConfigMap
metadata:
  name: flowcontrol
  namespace: aperture-system
  labels:
    aperture.tech/validate: "true"
apiVersion: v1
data:
  latency-gradient.yaml: |
    evaluation_interval: "0.5s"
    flux_meters:
      - name: "demo1_latency"
        selector:
          service: "demo1-demo-app.demoapp.svc.cluster.local"
          control_point:
            traffic: "ingress"
    circuit:
      - promql:
          query_string: "sum(increase(demo1_latency_sum[5s]))/sum(increase(demo1_latency_count[5s]))"
          evaluation_interval: "1s"
          out_ports:
            output:
              signal_name: "LATENCY"
      - constant:
          value: "2.0"
          out_ports:
            output:
              signal_name: "EMA_LIMIT_MULTIPLIER"
      - arithmetic_combinator:
          operator: "mul"
          in_ports:
            lhs:
              signal_name: "LATENCY"
            rhs:
              signal_name: "EMA_LIMIT_MULTIPLIER"
          out_ports:
            output:
              signal_name: "MAX_EMA"
      - ema:
          ema_window: "300s"
          warm_up_window: "10s"
          correction_factor_on_max_envelope_violation: "0.95"
          in_ports:
            input:
              signal_name: "LATENCY"
            max_envelope:
              signal_name: "MAX_EMA"
          out_ports:
            output:
              signal_name: "LATENCY_EMA"
      - gradient_controller:
          tolerance: "1.1"
          min_gradient: "0.1"
          max_gradient: "1.0"
          in_ports:
            signal:
              signal_name: "LATENCY"
            setpoint:
              signal_name: "LATENCY_EMA"
            max:
              signal_name: "MAX_CONCURRENCY"
            control_variable:
              signal_name: "ACCEPTED_CONCURRENCY"
            optimize:
              signal_name: "CONCURRENCY_INCREMENT"
          out_ports:
            output:
              signal_name: "DESIRED_CONCURRENCY"
      - arithmetic_combinator:
          operator: "sub"
          in_ports:
            lhs:
              signal_name: "INCOMING_CONCURRENCY"
            rhs:
              signal_name: "DESIRED_CONCURRENCY"
          out_ports:
            output:
              signal_name: "DELTA_CONCURRENCY"
      - arithmetic_combinator:
          operator: "div"
          in_ports:
            lhs:
              signal_name: "DELTA_CONCURRENCY"
            rhs:
              signal_name: "INCOMING_CONCURRENCY"
          out_ports:
            output:
              signal_name: "LSF"
      - concurrency_limiter:
          scheduler:
            selector:
              service: "demo1-demo-app.demoapp.svc.cluster.local"
              control_point:
                traffic: "ingress"
            workload_config:
              label_key: "flow_user"
              auto_tokens: true
              default_workload:
                priority: 20
                timeout: "0.005s"
              workloads:
                - label_value: "A"
                  priority: 50
                  timeout: "0.005s"
                - label_value: "B"
                  priority: 200
                  timeout: "0.005s"
            out_ports:
              accepted_concurrency:
                signal_name: "ACCEPTED_CONCURRENCY"
              incoming_concurrency:
                signal_name: "INCOMING_CONCURRENCY"
          load_shed_actuator:
            in_ports:
              load_shed_factor:
                signal_name: "LSF"
      - constant:
          value: "2.0"
          out_ports:
            output:
              signal_name: "CONCURRENCY_LIMIT_MULTIPLIER"
      - constant:
          value: "10.0"
          out_ports:
            output:
              signal_name: "MIN_CONCURRENCY"
      - constant:
          value: "5.0"
          out_ports:
            output:
              signal_name: "LINEAR_CONCURRENCY_INCREMENT"
      - arithmetic_combinator:
          operator: "mul"
          in_ports:
            lhs:
              signal_name: "CONCURRENCY_LIMIT_MULTIPLIER"
            rhs:
              signal_name: "ACCEPTED_CONCURRENCY"
          out_ports:
            output:
              signal_name: "UPPER_CONCURRENCY_LIMIT"
      - max:
          in_ports:
            inputs:
              - signal_name: "UPPER_CONCURRENCY_LIMIT"
              - signal_name: "MIN_CONCURRENCY"
          out_ports:
            output:
              signal_name: "MAX_CONCURRENCY"
      - sqrt:
          scale: "0.5"
          in_ports:
            input:
              signal_name: "ACCEPTED_CONCURRENCY"
          out_ports:
            output:
              signal_name: "SQRT_CONCURRENCY_INCREMENT"
      - arithmetic_combinator:
          operator: "add"
          in_ports:
            lhs:
              signal_name: "LINEAR_CONCURRENCY_INCREMENT"
            rhs:
              signal_name: "SQRT_CONCURRENCY_INCREMENT"
          out_ports:
            output:
              signal_name: "CONCURRENCY_INCREMENT_NORMAL"
      - constant:
          value: "1.2"
          out_ports:
            output:
              signal_name: "OVERLOAD_MULTIPLIER"
      - arithmetic_combinator:
          operator: "mul"
          in_ports:
            lhs:
              signal_name: "LATENCY_EMA"
            rhs:
              signal_name: "OVERLOAD_MULTIPLIER"
          out_ports:
            output:
              signal_name: "LATENCY_OVERLOAD"
      - constant:
          value: "10.0"
          out_ports:
            output:
              signal_name: "CONCURRENCY_INCREMENT_OVERLOAD"
      - decider:
          operator: "gt"
          in_ports:
            lhs:
              signal_name: "LATENCY"
            rhs:
              signal_name: "LATENCY_OVERLOAD"
            on_true:
              signal_name: "CONCURRENCY_INCREMENT_OVERLOAD"
            on_false:
              signal_name: "CONCURRENCY_INCREMENT_NORMAL"
          out_ports:
            output:
              signal_name: "CONCURRENCY_INCREMENT"
import http from "k6/http";
import { check } from "k6";

export let options = {
  discardResponseBodies: true,
  scenarios: {
    userA: {
      executor: "ramping-vus",
      stages: [
        { duration: "30s", target: 5 }, // simulate ramp-up of traffic from 0 to 5 users over 30 seconds
        { duration: "2m", target: 5 }, // stay at 5 users for 2 minutes
        { duration: "30s", target: 60 }, // ramp-up to 60 users over 30 seconds
        { duration: "4m", target: 60 }, // stay at 60 users for 4 minutes (peak hour)
        { duration: "1m", target: 0 }, // ramp-down to 0 users in 1 minute
      ],
      env: { USER: "A" },
    },
    userB: {
      executor: "ramping-vus",
      stages: [
        { duration: "30s", target: 5 }, // simulate ramp-up of traffic from 0 to 5 users over 30 seconds
        { duration: "2m", target: 5 }, // stay at 5 users for 2 minutes
        { duration: "30s", target: 60 }, // ramp-up to 60 users over 30 seconds
        { duration: "4m", target: 60 }, // stay at 60 users for 4 minutes (peak hour)
        { duration: "1m", target: 0 }, // ramp-down to 0 users in 1 minute
      ],
      env: { USER: "B" },
    },
  },
};

export default function () {
  let user = __ENV.USER;
  const url = "http://demo1-demo-app.demoapp.svc.cluster.local/request";
  const headers = {
    "Content-Type": "application/json",
    Cookie:
      "session=eyJ1c2VyIjoia2Vub2JpIn0.YbsY4Q.kTaKRTyOIfVlIbNB48d9YH6Q0wo",
    User: user,
  };
  const body = {};
  let res = http.request("POST", url, JSON.stringify(body), {
    headers: headers,
  });
  check(res, {
    "http status was 200": res.status === 200,
  });
}

Below is the result from druid:
image

  1. In this case, I have added a new user and used the same policy and classification as above. Here also, the drop rates were almost similar for different priority loads.

Below is the load-test.js for this scenario:

import http from "k6/http";
import { check } from "k6";

export let options = {
  discardResponseBodies: true,
  scenarios: {
    userA: {
      executor: "ramping-vus",
      stages: [
        { duration: "30s", target: 5 }, // simulate ramp-up of traffic from 0 to 5 users over 30 seconds
        { duration: "2m", target: 5 }, // stay at 5 users for 2 minutes
        { duration: "30s", target: 60 }, // ramp-up to 60 users over 30 seconds
        { duration: "4m", target: 60 }, // stay at 60 users for 4 minutes (peak hour)
        { duration: "1m", target: 0 }, // ramp-down to 0 users in 1 minute
      ],
      env: { USER: "A" },
    },
    userB: {
      executor: "ramping-vus",
      stages: [
        { duration: "30s", target: 5 }, // simulate ramp-up of traffic from 0 to 5 users over 30 seconds
        { duration: "2m", target: 5 }, // stay at 5 users for 2 minutes
        { duration: "30s", target: 60 }, // ramp-up to 60 users over 30 seconds
        { duration: "4m", target: 60 }, // stay at 60 users for 4 minutes (peak hour)
        { duration: "1m", target: 0 }, // ramp-down to 0 users in 1 minute
      ],
      env: { USER: "B" },
    },
    userC: {
      executor: "ramping-vus",
      stages: [
        { duration: "30s", target: 5 }, // simulate ramp-up of traffic from 0 to 5 users over 30 seconds
        { duration: "2m", target: 5 }, // stay at 5 users for 2 minutes
        { duration: "30s", target: 60 }, // ramp-up to 60 users over 30 seconds
        { duration: "4m", target: 60 }, // stay at 60 users for 4 minutes (peak hour)
        { duration: "1m", target: 0 }, // ramp-down to 0 users in 1 minute
      ],
      env: { USER: "C" },
    },
  },
};

export default function () {
  let user = __ENV.USER;
  const url = "http://demo1-demo-app.demoapp.svc.cluster.local/request";
  const headers = {
    "Content-Type": "application/json",
    Cookie:
      "session=eyJ1c2VyIjoia2Vub2JpIn0.YbsY4Q.kTaKRTyOIfVlIbNB48d9YH6Q0wo",
    User: user,
  };
  const body = {};
  let res = http.request("POST", url, JSON.stringify(body), {
    headers: headers,
  });
  check(res, {
    "http status was 200": res.status === 200,
  });
}

Below is the result from druid:
image

As we have different priorities for different users, the drop rate shouldn't be same and should be much lower for higher priority loads.

Examples are not rendered in docs

We have examples in attributes in proto definitions, but our swagger template doesn't include them.

Possible fix: just put example as regular doc comment (as before)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.