Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# 项目简介
## 目录划分:
core : 核心实现
example : 示例代码


11 changes: 11 additions & 0 deletions core/node/metric_node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package node

type MetricNode struct {
Timestamp uint64
PassQps uint64
BlockQps uint64
SuccessQps uint64
ErrorQps uint64
Rt uint64
Resource string
}
34 changes: 34 additions & 0 deletions core/node/node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package node

type Node interface {
//TotalRequest() uint64
//TotalPass() uint64
TotalSuccess() uint64
//BlockRequest() uint64
//TotalError() uint64
//PassQps() uint64
//BlockQps() uint64
//TotalQps() uint64
//SuccessQps() uint64
//MaxSuccessQps() uint64
//ErrorQps() uint64
//AvgRt() float32
//MinRt() float32
//CurGoroutineNum() uint64

//PreviousBlockQps() uint64
//PreviousPassQps() uint64
//
//Metrics() map[uint64]*metrics.MetricNode

AddPassRequest(count uint32)
//AddRtAndSuccess(rt uint64, success uint32)
//
//IncreaseBlockQps(count uint32)
//IncreaseErrorQps(count uint32)
//
//IncreaseGoroutineNum()
//DecreaseGoroutineNum()

//Reset()
}
8 changes: 8 additions & 0 deletions core/property/property.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package property

//PropertyListener
type PropertyListener interface {
ConfigUpdate(value interface{})

ConfigLoad(value interface{})
}
6 changes: 6 additions & 0 deletions core/slots/base/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package base

const (
INBOUND = iota
OUTBOUND
)
13 changes: 13 additions & 0 deletions core/slots/base/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package base

import (
"context"
)

type Context struct {
name string
entranceNode DefaultNode
curEntry Entry
origin string
context context.Context
}
93 changes: 93 additions & 0 deletions core/slots/base/default_node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package base

import (
"github.com/sentinel-group/sentinel-golang/core/node"
"github.com/sentinel-group/sentinel-golang/core/slots/statistic/data"
"github.com/sentinel-group/sentinel-golang/core/util"
"sync/atomic"
)

const (
windowLengthImMs_ uint32 = 200
sampleCount_ uint32 = 5
intervalInMs_ uint32 = 1000
)

type DefaultNode struct {
rollingCounterInSecond *data.SlidingWindow
rollingCounterInMinute *data.SlidingWindow
currentGoroutineNum uint32
lastFetchTime uint64
resourceWrapper *ResourceWrapper
}

func NewDefaultNode(wrapper *ResourceWrapper) *DefaultNode {
return &DefaultNode{
rollingCounterInSecond: data.NewSlidingWindow(sampleCount_, intervalInMs_),
rollingCounterInMinute: data.NewSlidingWindow(sampleCount_, intervalInMs_),
currentGoroutineNum: 0,
lastFetchTime: util.GetTimeMilli(),
resourceWrapper: wrapper,
}
}

func (dn *DefaultNode) AddPass(count uint64) {
dn.rollingCounterInSecond.AddCount(data.MetricEventPass, count)
}

func (dn *DefaultNode) AddGoroutineNum(count uint32) {
atomic.AddUint32(&dn.currentGoroutineNum, count)
}

func (dn *DefaultNode) TotalRequest() uint64 {
return dn.rollingCounterInSecond.Count(data.MetricEventPass) + dn.rollingCounterInSecond.Count(data.MetricEventBlock)
}
func (dn *DefaultNode) TotalPass() uint64 {
return dn.rollingCounterInMinute.Count(data.MetricEventPass)
}
func (dn *DefaultNode) TotalSuccess() uint64 {
return dn.rollingCounterInMinute.Count(data.MetricEventSuccess)
}
func (dn *DefaultNode) BlockRequest() uint64 {
return dn.rollingCounterInMinute.Count(data.MetricEventBlock)
}
func (dn *DefaultNode) TotalError() uint64 {
return dn.rollingCounterInMinute.Count(data.MetricEventError)
}
func (dn *DefaultNode) PassQps() uint64 {
return dn.rollingCounterInSecond.Count(data.MetricEventPass) / uint64(intervalInMs_)
}
func (dn *DefaultNode) BlockQps() uint64 {
return dn.rollingCounterInSecond.Count(data.MetricEventBlock) / uint64(intervalInMs_)
}
func (dn *DefaultNode) TotalQps() uint64 {
return dn.PassQps() + dn.BlockQps()
}
func (dn *DefaultNode) SuccessQps() uint64 {
return dn.rollingCounterInSecond.Count(data.MetricEventSuccess) / uint64(intervalInMs_)
}
func (dn *DefaultNode) MaxSuccessQps() uint64 {
return dn.rollingCounterInSecond.MaxSuccess() * uint64(sampleCount_)
}
func (dn *DefaultNode) ErrorQps() uint64 {
return dn.rollingCounterInSecond.Count(data.MetricEventError) / uint64(intervalInMs_)
}

func (dn *DefaultNode) AvgRt() float32 {
return 0
}
func (dn *DefaultNode) MinRt() float32 {
return 0
}
func (dn *DefaultNode) CurGoroutineNum() uint64 {
return 0
}
func (dn *DefaultNode) PreviousBlockQps() uint64 {
return 0
}
func (dn *DefaultNode) PreviousPassQps() uint64 {
return 0
}
func (dn *DefaultNode) Metrics() map[uint64]*node.MetricNode {
return nil
}
13 changes: 13 additions & 0 deletions core/slots/base/entry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package base

import (
"github.com/sentinel-group/sentinel-golang/core/node"
)

type Entry struct {
createTime uint64
originNode node.Node
currentNode node.Node
resourceWrap *ResourceWrapper
err error
}
46 changes: 46 additions & 0 deletions core/slots/base/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @description:
*
* @author: helloworld
* @date:2019-07-11
*/
package base

type ResourceWrapper struct {
// unique resource name
ResourceName string
//
ResourceType int
}

type SlotResultStatus int8

const (
ResultStatusPass = iota
ResultStatusBlocked
ResultStatusWait
ResultStatusError
)

type TokenResult struct {
Status SlotResultStatus
BlockedReason string
WaitMs uint64
ErrorMsg string
}

func NewSlotResultPass() *TokenResult {
return &TokenResult{Status: ResultStatusPass}
}

func NewSlotResultBlock(blockedReason string) *TokenResult {
return &TokenResult{Status: ResultStatusBlocked, BlockedReason: blockedReason}
}

func NewSlotResultWait(waitMs uint64) *TokenResult {
return &TokenResult{Status: ResultStatusWait, WaitMs: waitMs}
}

func NewSlotResultError(errorMsg string) *TokenResult {
return &TokenResult{Status: ResultStatusError, ErrorMsg: errorMsg}
}
66 changes: 66 additions & 0 deletions core/slots/chain/slot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package chain

import (
"github.com/sentinel-group/sentinel-golang/core/slots/base"
)

// a solt
type Slot interface {
/**
* Entrance of this slots.
*/
Entry(ctx *base.Context, resWrapper *base.ResourceWrapper, node *base.DefaultNode, count int, prioritized bool) (*base.TokenResult, error)

Exit(context *base.Context, resourceWrapper *base.ResourceWrapper, count int) error

// 传递进入
FireEntry(context *base.Context, resourceWrapper *base.ResourceWrapper, defaultNode *base.DefaultNode, count int, prioritized bool) (*base.TokenResult, error)

// 传递退出
FireExit(context *base.Context, resourceWrapper *base.ResourceWrapper, count int) error

GetNext() Slot

SetNext(next Slot)
}

// a slot can make slot compose linked
type LinkedSlot struct {
// next linkedSlot
next Slot
}

// 传递退出
func (s *LinkedSlot) Entry(ctx *base.Context, resWrapper *base.ResourceWrapper, node *base.DefaultNode, count int, prioritized bool) (*base.TokenResult, error) {
return s.FireEntry(ctx, resWrapper, node, count, prioritized)
}

// 传递进入
func (s *LinkedSlot) Exit(context *base.Context, resourceWrapper *base.ResourceWrapper, count int) error {
return s.FireExit(context, resourceWrapper, count)
}

// 传递进入, 没有下一个就返回 ResultStatusPass
func (s *LinkedSlot) FireEntry(context *base.Context, resourceWrapper *base.ResourceWrapper, defaultNode *base.DefaultNode, count int, prioritized bool) (*base.TokenResult, error) {
if s.next != nil {
return s.next.Entry(context, resourceWrapper, defaultNode, count, prioritized)
}
return base.NewSlotResultPass(), nil
}

// 传递退出,没有下一个就返回
func (s *LinkedSlot) FireExit(context *base.Context, resourceWrapper *base.ResourceWrapper, count int) error {
if s.next != nil {
return s.next.Exit(context, resourceWrapper, count)
} else {
return nil
}
}

func (s *LinkedSlot) GetNext() Slot {
return s.next
}

func (s *LinkedSlot) SetNext(next Slot) {
s.next = next
}
63 changes: 63 additions & 0 deletions core/slots/chain/slot_chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package chain

import (
"github.com/sentinel-group/sentinel-golang/core/slots/base"
)

type SlotChain interface {
/**
* Add a processor to the head of this slots slotchain.
*
* @param protocolProcessor processor to be added.
*/
AddFirst(slot Slot)

/**
* Add a processor to the tail of this slots slotchain.
*
* @param protocolProcessor processor to be added.
*/
AddLast(slot Slot)

// fire to next slot
Entry(context *base.Context, resourceWrapper *base.ResourceWrapper, defaultNode *base.DefaultNode, count int, prioritized bool) (*base.TokenResult, error)
// fire to next slot
Exit(context *base.Context, resourceWrapper *base.ResourceWrapper, count int) error
}

// implent SlotChain
type LinkedSlotChain struct {
first Slot
end Slot
}

func NewLinkedSlotChain() *LinkedSlotChain {
fs := new(LinkedSlot)
return &LinkedSlotChain{first: fs, end: fs}
}

func (lsc *LinkedSlotChain) AddFirst(slot Slot) {
slot.SetNext(lsc.first.GetNext())
lsc.first.SetNext(slot)
if lsc.end == lsc.first {
lsc.end = slot
}
}

func (lsc *LinkedSlotChain) AddLast(slot Slot) {
lsc.end.SetNext(slot)
lsc.end = slot
}

func (lsc *LinkedSlotChain) Entry(context *base.Context, resourceWrapper *base.ResourceWrapper, defaultNode *base.DefaultNode, count int, prioritized bool) (*base.TokenResult, error) {
return lsc.first.Entry(context, resourceWrapper, defaultNode, count, prioritized)
}

// 传递进入
func (lsc *LinkedSlotChain) Exit(context *base.Context, resourceWrapper *base.ResourceWrapper, count int) error {
return lsc.first.Exit(context, resourceWrapper, count)
}

type SlotChainBuilder interface {
Build() SlotChain
}
Loading