//  Copyright(C) 2021. Huawei Technologies Co.,Ltd.  All rights reserved.

// Package limiter implement a token bucket limiter
package limiter

import (
"context"
"huawei.com/npu-exporter/hwlog"
"huawei.com/npu-exporter/utils"
"math"
"net/http"
"time"
)

const (
kilo = 1000.0
)

type limitHandler struct {
concurrency chan struct{}
httpHandler http.Handler
log bool
}

// ServeHTTP implement http.Handler
func (h *limitHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
ctx := context.TODO()
reqID := req.Header.Get(hwlog.ReqID.String())
if reqID != "" {
ctx = context.WithValue(context.Background(), hwlog.ReqID, reqID)
}
id := req.Header.Get(hwlog.UserID.String())
if id != "" {
ctx = context.WithValue(ctx, hwlog.UserID, id)
}
path := req.URL.Path
clientIP := utils.ClientIP(req)
clientUserAgent := req.UserAgent()
select {
case _, ok := <-h.concurrency:
if !ok {
return
}
start := time.Now()
h.httpHandler.ServeHTTP(w, req)
stop := time.Since(start)
latency := int(math.Ceil(float64(stop.Nanoseconds()) / kilo / kilo))
if h.log {
hwlog.RunLog.InfofWithCtx(ctx, "%s %s: %s <%3d> (%dms) |%15s |%s ", req.Proto, req.Method, path,
http.StatusOK, latency, clientIP, clientUserAgent)
}
h.concurrency <- struct{}{}
default:
hwlog.RunLog.WarnfWithCtx(ctx, "Reject Request:%s: %s <%3d> |%15s |%s ", req.Method, path,
http.StatusServiceUnavailable, clientIP, clientUserAgent)
http.Error(w, "503 too busy", http.StatusServiceUnavailable)
}
}

// NewLimitHandler new a bucket-token limiter
func NewLimitHandler(maxConcur, maxConcurrency int, handler http.Handler, printLog bool) http.Handler {
if maxConcur < 1 || maxConcur > maxConcurrency {
hwlog.RunLog.Fatal("maxConcurrency parameter error")
}
h := &limitHandler{
concurrency: make(chan struct{}, maxConcur),
httpHandler: handler,
log: printLog,
}
for i := 0; i < maxConcur; i++ {
h.concurrency <- struct{}{}
}
return h
}

hwlog--limiter.go的更多相关文章

  1. Cannot send session cache limiter Cannot modify header information

    当php报出  Cannot send session cache limiter 或Cannot modify header information   的错误时   其理论上是因为php代码以前有 ...

  2. Warning: session_start() [function.session-start]: Cannot send session cache limiter

    Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers alrea ...

  3. go笔记-限速器(limiter)

    参考: https://blog.csdn.net/wdy_yx/article/details/73849713https://www.jianshu.com/p/1ecb513f7632 http ...

  4. ICD2 VPP limiter for new PIC microcontrollers.

    http://www.circuitsathome.com/mcu/pic_vpp_limiter VOUT = 2.5V * ( 1 + 24/10 ) = 2.5 * 3.4 = 8.5V New ...

  5. rate limiter - system design

    1 问题 Whenever you expose a web service / api endpoint, you need to implement a rate limiter to preve ...

  6. 359. Logger Rate Limiter

    /* * 359. Logger Rate Limiter * 2016-7-14 by Mingyang * 很简单的HashMap,不详谈 */ class Logger { HashMap< ...

  7. Rate Limiter

    Whenever you expose a web service / api endpoint, you need to implement a rate limiter to prevent ab ...

  8. RocksDB Rate Limiter源码解析

    这次的项目我们重点关注RocksDB中的一个环节:Rate Limiter.其实Rate Limiter的思想在很多其他系统中也很常用. 在RocksDB中,后台会实时运行compaction和flu ...

  9. 详解FL Studio压缩器——Fruity Limiter(上)

    压缩,是电音制作中重要一步,将声音信号压缩后可过滤噪音并使音质变好.众所周知,音乐编曲软件FL Studio的特色就是电音制作,所以必不可少要用到压缩器,今天我们就用FL Studio20来讲解一下. ...

  10. 详解FL Studio压缩器——Fruity Limiter(下)

    Hello!小伙伴们又见面啦-接上一篇,本篇咱们继续讲解音乐编曲软件FL Studio20压缩器内容. 包络"ENVELOPE"中包含三个旋钮,它们都有什么作用呢?一起来揭晓吧! ...

随机推荐

  1. kingbaseES R3 集群配置 SSL

    ​ 案例说明: 本测试是在非生产环境下,在官方没有明确声明支持KingbaseCluster使用ssl的前提下,建议只能在测试环境使用,避免生产环境下直接使用. 数据库版本: TEST=# selec ...

  2. 新一代网络请求库:python-httpx库

    目录 httpx库 一. 概述 1. 简介 2. 命令行模式 3. 快速开始 3.1 get请求 3.2 post请求 3.2.1 表单 3.2.2 文件 3.2.3 JSON 3.2.4 二进制 3 ...

  3. JDK自带javap命令反编译class文件和Jad反编译class文件(推荐使用jad)

    一.前言 我们在日常学习中,对一个java代码有问题,不知道jvm内部怎么进行解析的时候:有个伟大壮举就是反编译,这样就可以看到jvm内部怎么进行对这个java文件解析的!我们可以使用JDK自带的ja ...

  4. 如何在Windows中查询证书颁发机构已颁发的证书

    有时候需要看一下证书颁发机构已经颁发出去的证书,看看某个用户或者某个计算机获取过的证书有哪些.通常可以在证书颁发机构的MMC中查看.对于测试环境或者刚开始用的CA来说,这样查看挺简单的.但是对于用了一 ...

  5. 6、Arrays类

    Arrays类 Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索) 常用方法 toString 返回数组的字符串形式 Arrays.toString(arr) Integer[ ...

  6. 合理编写C++模块(.h、.cc)

    模块划分 合理编写模块的 demo.h.demo.cc 下例为C++为后端服务编写的探活检测服务 health_server.h #ifndef HEALTH_SERVER_H #define HEA ...

  7. 路径参数和数值校验: Path_Parameters_and_Numeric_Validations

    官方文档地址: https://fastapi.tiangolo.com/zh/tutorial/path-params-numeric-validations/ # -*- coding: UTF- ...

  8. Kibana管理

    这里是用来管理您的 kibana 运行时配置的地方,包括初始化配置和后续的索引模式配置.高级设置等.您可以调整 kibana 自身的行为,也可以编辑您通过 kibana 保存的查询.视图.仪表板等各种 ...

  9. 组件化开发3-cocoaPods私有库制作

    一.创建索引项目ZHMCSSpec 1-1 在代码托管网站上建立索引项目ZHMCSSpec(以这个名称为例) 1-2 在本地创建ZHMCSSpec,并与远程索引建立联系 pod repo add ZH ...

  10. Python——索引与切片

    #索引与切片 ##1.序列 序列:list,tuple,str 其中list是可变序列 typle,str是不可变序列 #修改序列的值 list = [3,4,5] tup = (3,4,5) str ...