Repository: alibaba/sentinel-golang
Pull request #263 (2020-10-03 08:30:03)

Mod: acquire -> batch
<!--  Thanks for submitting a pull request! Here are some tips for you:
1. Please make sure you have read and understood the contributing guidelines: https://github.com/alibaba/blob/master/CONTRIBUTING.md
2. Please make sure the PR has a corresponding issue.
-->

### Describe what this PR does / why we need it

change the acquire count which I do not understand to batch count


CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/alibaba/sentinel-golang?pullRequest=263) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/alibaba/sentinel-golang?pullRequest=263) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/alibaba/sentinel-golang?pullRequest=263) it.</sub>
codecov-commenter: # [Codecov](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=h1) Report
> Merging [#263](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=desc) into [master](https://codecov.io/gh/alibaba/sentinel-golang/commit/124be278983ca4b047ae57997a9d261388c5d09f?el=desc) will **decrease** coverage by `0.02%`.
> The diff coverage is `62.85%`.

[![Impacted file tree graph](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/graphs/tree.svg?width=650&height=150&src=pr&token=SrpzbhKA3E)](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #263      +/-   ##
==========================================
- Coverage   42.82%   42.80%   -0.03%     
==========================================
  Files          79       79              
  Lines        4014     4016       +2     
==========================================
  Hits         1719     1719              
- Misses       2030     2032       +2     
  Partials      265      265              
```


| [Impacted Files](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [core/flow/tc\_default.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9mbG93L3RjX2RlZmF1bHQuZ28=) | `68.75% <0.00%> (ø)` | |
| [core/hotspot/slot.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9ob3RzcG90L3Nsb3QuZ28=) | `34.14% <0.00%> (ø)` | |
| [core/isolation/slot.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9pc29sYXRpb24vc2xvdC5nbw==) | `0.00% <0.00%> (ø)` | |
| [api/api.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-YXBpL2FwaS5nbw==) | `34.32% <33.33%> (-1.06%)` | :arrow_down: |
| [core/flow/tc\_throttling.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9mbG93L3RjX3Rocm90dGxpbmcuZ28=) | `62.96% <50.00%> (ø)` | |
| [core/hotspot/traffic\_shaping.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9ob3RzcG90L3RyYWZmaWNfc2hhcGluZy5nbw==) | `60.13% <87.50%> (ø)` | |
| [core/base/context.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9iYXNlL2NvbnRleHQuZ28=) | `51.51% <100.00%> (ø)` | |
| [core/base/slot\_chain.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9iYXNlL3Nsb3RfY2hhaW4uZ28=) | `97.01% <100.00%> (ø)` | |
| [core/flow/slot.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9mbG93L3Nsb3QuZ28=) | `42.85% <100.00%> (ø)` | |
| [core/flow/standalone\_stat\_slot.go](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree#diff-Y29yZS9mbG93L3N0YW5kYWxvbmVfc3RhdF9zbG90Lmdv) | `66.66% <100.00%> (ø)` | |
| ... and [1 more](https://codecov.io/gh/alibaba/sentinel-golang/pull/263/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=footer). Last update [124be27...39b32f7](https://codecov.io/gh/alibaba/sentinel-golang/pull/263?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/api/api.go b/api/api.go
index 55c8f2f..1bff3c0 100644
--- a/api/api.go
+++ b/api/api.go
@@ -11,7 +11,7 @@ var entryOptsPool = sync.Pool{
 		return &EntryOptions{
 			resourceType: base.ResTypeCommon,
 			entryType:    base.Outbound,
-			acquireCount: 1,
+			batchCount:   1,
 			flag:         0,
 			slotChain:    nil,
 			args:         nil,
@@ -24,7 +24,7 @@ var entryOptsPool = sync.Pool{
 type EntryOptions struct {
 	resourceType base.ResourceType
 	entryType    base.TrafficType
-	acquireCount uint32
+	batchCount   uint32
 	flag         int32
 	slotChain    *base.SlotChain
 	args         []interface{}
@@ -34,7 +34,7 @@ type EntryOptions struct {
 func (o *EntryOptions) Reset() {
 	o.resourceType = base.ResTypeCommon
 	o.entryType = base.Outbound
-	o.acquireCount = 1
+	o.batchCount = 1
 	o.flag = 0
 	o.slotChain = nil
 	o.args = nil
@@ -57,10 +57,18 @@ func WithTrafficType(entryType base.TrafficType) EntryOption {
 	}
 }
 
+// DEPRECATED: use WithBatchCount instead.
 // WithAcquireCount sets the resource entry with the given batch count (by default 1).
 func WithAcquireCount(acquireCount uint32) EntryOption {
 	return func(opts *EntryOptions) {
-		opts.acquireCount = acquireCount
+		opts.batchCount = acquireCount
+	}
+}
+
+// WithBatchCount sets the resource entry with the given batch count (by default 1).
+func WithBatchCount(batchCount uint32) EntryOption {
+	return func(opts *EntryOptions) {
+		opts.batchCount = batchCount
 	}
 }
 
@@ -129,7 +137,7 @@ func entry(resource string, options *EntryOptions) (*base.SentinelEntry, *base.B
 	// Get context from pool.
 	ctx := sc.GetPooledContext()
 	ctx.Resource = rw
-	ctx.Input.AcquireCount = options.acquireCount
+	ctx.Input.BatchCount = options.batchCount
 	ctx.Input.Flag = options.flag
 	if len(options.args) != 0 {
 		ctx.Input.Args = options.args
diff --git a/core/base/context.go b/core/base/context.go
index 99660e2..be75a85 100644
--- a/core/base/context.go
+++ b/core/base/context.go
@@ -67,15 +67,15 @@ func NewEmptyEntryContext() *EntryContext {
 
 // The input data of sentinel
 type SentinelInput struct {
-	AcquireCount uint32
-	Flag         int32
-	Args         []interface{}
+	BatchCount uint32
+	Flag       int32
+	Args       []interface{}
 	// store some values in this context when calling context in slot.
 	Attachments map[interface{}]interface{}
 }
 
 func (i *SentinelInput) reset() {
-	i.AcquireCount = 1
+	i.BatchCount = 1
 	i.Flag = 0
 	if len(i.Args) != 0 {
 		i.Args = make([]interface{}, 0)
diff --git a/core/base/slot_chain.go b/core/base/slot_chain.go
index b8e507d..f2cb82b 100644
--- a/core/base/slot_chain.go
+++ b/core/base/slot_chain.go
@@ -67,10 +67,10 @@ func NewSlotChain() *SlotChain {
 				ctx.RuleCheckResult = NewTokenResultPass()
 				ctx.Data = make(map[interface{}]interface{})
 				ctx.Input = &SentinelInput{
-					AcquireCount: 1,
-					Flag:         0,
-					Args:         make([]interface{}, 0),
-					Attachments:  make(map[interface{}]interface{}),
+					BatchCount:  1,
+					Flag:        0,
+					Args:        make([]interface{}, 0),
+					Attachments: make(map[interface{}]interface{}),
 				}
 				return ctx
 			},
diff --git a/core/config/config.go b/core/config/config.go
index c6ae304..7a96ea7 100644
--- a/core/config/config.go
+++ b/core/config/config.go
@@ -3,6 +3,7 @@ package config
 import (
 	"io/ioutil"
 	"os"
+	"path/filepath"
 	"strconv"
 	"sync"
 
@@ -137,8 +138,7 @@ func initializeLogConfig(logDir string, usePid bool) (err error) {
 }
 
 func reconfigureRecordLogger(logBaseDir string, withPid bool) error {
-	logDir := util.AddPathSeparatorIfAbsent(logBaseDir)
-	filePath := logDir + logging.RecordLogFileName
+	filePath := filepath.Join(logBaseDir, logging.RecordLogFileName)
 	if withPid {
 		filePath = filePath + ".pid" + strconv.Itoa(os.Getpid())
 	}
@@ -152,7 +152,7 @@ func reconfigureRecordLogger(logBaseDir string, withPid bool) error {
 		return err
 	}
 
-	logging.Info("INFO: log base directory is: " + logDir)
+	logging.Info("INFO: log base directory is: " + logBaseDir)
 
 	return nil
 }
@@ -162,7 +162,7 @@ func GetDefaultLogDir() string {
 	if err != nil {
 		return ""
 	}
-	return util.AddPathSeparatorIfAbsent(home) + logging.DefaultDirName
+	return filepath.Join(home, logging.DefaultDirName)
 }
 
 func AppName() string {
diff --git a/core/flow/slot.go b/core/flow/slot.go
index 5776c03..d7b5ecc 100644
--- a/core/flow/slot.go
+++ b/core/flow/slot.go
@@ -23,7 +23,7 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 			logging.Warn("nil traffic controller found", "resourceName", res)
 			continue
 		}
-		r := canPassCheck(tc, ctx.StatNode, ctx.Input.AcquireCount)
+		r := canPassCheck(tc, ctx.StatNode, ctx.Input.BatchCount)
 		if r == nil {
 			// nil means pass
 			continue
@@ -42,12 +42,12 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 	return result
 }
 
-func canPassCheck(tc *TrafficShapingController, node base.StatNode, acquireCount uint32) *base.TokenResult {
-	return canPassCheckWithFlag(tc, node, acquireCount, 0)
+func canPassCheck(tc *TrafficShapingController, node base.StatNode, batchCount uint32) *base.TokenResult {
+	return canPassCheckWithFlag(tc, node, batchCount, 0)
 }
 
-func canPassCheckWithFlag(tc *TrafficShapingController, node base.StatNode, acquireCount uint32, flag int32) *base.TokenResult {
-	return checkInLocal(tc, node, acquireCount, flag)
+func canPassCheckWithFlag(tc *TrafficShapingController, node base.StatNode, batchCount uint32, flag int32) *base.TokenResult {
+	return checkInLocal(tc, node, batchCount, flag)
 }
 
 func selectNodeByRelStrategy(rule *Rule, node base.StatNode) base.StatNode {
@@ -57,7 +57,7 @@ func selectNodeByRelStrategy(rule *Rule, node base.StatNode) base.StatNode {
 	return node
 }
 
-func checkInLocal(tc *TrafficShapingController, resStat base.StatNode, acquireCount uint32, flag int32) *base.TokenResult {
+func checkInLocal(tc *TrafficShapingController, resStat base.StatNode, batchCount uint32, flag int32) *base.TokenResult {
 	actual := selectNodeByRelStrategy(tc.rule, resStat)
 	if actual == nil {
 		logging.FrequentErrorOnce.Do(func() {
@@ -65,5 +65,5 @@ func checkInLocal(tc *TrafficShapingController, resStat base.StatNode, acquireCo
 		})
 		return base.NewTokenResultPass()
 	}
-	return tc.PerformChecking(actual, acquireCount, flag)
+	return tc.PerformChecking(actual, batchCount, flag)
 }
diff --git a/core/flow/standalone_stat_slot.go b/core/flow/standalone_stat_slot.go
index a69f5d3..08164cb 100644
--- a/core/flow/standalone_stat_slot.go
+++ b/core/flow/standalone_stat_slot.go
@@ -14,7 +14,7 @@ func (s StandaloneStatSlot) OnEntryPassed(ctx *base.EntryContext) {
 	for _, tc := range getTrafficControllerListFor(res) {
 		if !tc.boundStat.reuseResourceStat {
 			if tc.boundStat.writeOnlyMetric != nil {
-				tc.boundStat.writeOnlyMetric.AddCount(base.MetricEventPass, int64(ctx.Input.AcquireCount))
+				tc.boundStat.writeOnlyMetric.AddCount(base.MetricEventPass, int64(ctx.Input.BatchCount))
 			} else {
 				logging.Error(errors.New("nil independent write statistic"), "flow module: nil statistic for traffic control", "rule", tc.rule)
 			}
diff --git a/core/flow/tc_default.go b/core/flow/tc_default.go
index 9e12096..f2807af 100644
--- a/core/flow/tc_default.go
+++ b/core/flow/tc_default.go
@@ -40,13 +40,13 @@ func (d *RejectTrafficShapingChecker) BoundOwner() *TrafficShapingController {
 	return d.owner
 }
 
-func (d *RejectTrafficShapingChecker) DoCheck(resStat base.StatNode, acquireCount uint32, threshold float64) *base.TokenResult {
+func (d *RejectTrafficShapingChecker) DoCheck(resStat base.StatNode, batchCount uint32, threshold float64) *base.TokenResult {
 	metricReadonlyStat := d.BoundOwner().boundStat.readOnlyMetric
 	if metricReadonlyStat == nil {
 		return nil
 	}
 	curCount := float64(metricReadonlyStat.GetSum(base.MetricEventPass))
-	if curCount+float64(acquireCount) > threshold {
+	if curCount+float64(batchCount) > threshold {
 		return base.NewTokenResultBlockedWithCause(base.BlockTypeFlow, "", d.rule, curCount)
 	}
 	return nil
diff --git a/core/flow/tc_throttling.go b/core/flow/tc_throttling.go
index ebbb03a..b7b1ec7 100644
--- a/core/flow/tc_throttling.go
+++ b/core/flow/tc_throttling.go
@@ -29,9 +29,9 @@ func (c *ThrottlingChecker) BoundOwner() *TrafficShapingController {
 	return c.owner
 }
 
-func (c *ThrottlingChecker) DoCheck(_ base.StatNode, acquireCount uint32, threshold float64) *base.TokenResult {
-	// Pass when acquire count is less or equal than 0.
-	if acquireCount <= 0 {
+func (c *ThrottlingChecker) DoCheck(_ base.StatNode, batchCount uint32, threshold float64) *base.TokenResult {
+	// Pass when batch count is less or equal than 0.
+	if batchCount <= 0 {
 		return nil
 	}
 	if threshold <= 0 {
@@ -40,7 +40,7 @@ func (c *ThrottlingChecker) DoCheck(_ base.StatNode, acquireCount uint32, thresh
 	// Here we use nanosecond so that we could control the queueing time more accurately.
 	curNano := util.CurrentTimeNano()
 	// The interval between two requests (in nanoseconds).
-	interval := uint64(math.Ceil(float64(acquireCount) / threshold * float64(nanoUnitOffset)))
+	interval := uint64(math.Ceil(float64(batchCount) / threshold * float64(nanoUnitOffset)))
 
 	// Expected pass time of this request.
 	expectedTime := atomic.LoadUint64(&c.lastPassedTime) + interval
diff --git a/core/flow/traffic_shaping.go b/core/flow/traffic_shaping.go
index 0ece11f..a93d5f7 100644
--- a/core/flow/traffic_shaping.go
+++ b/core/flow/traffic_shaping.go
@@ -8,14 +8,14 @@ import (
 // based on the threshold of rule and the traffic shaping strategy.
 type TrafficShapingCalculator interface {
 	BoundOwner() *TrafficShapingController
-	CalculateAllowedTokens(acquireCount uint32, flag int32) float64
+	CalculateAllowedTokens(batchCount uint32, flag int32) float64
 }
 
 // TrafficShapingChecker performs checking according to current metrics and the traffic
 // shaping strategy, then yield the token result.
 type TrafficShapingChecker interface {
 	BoundOwner() *TrafficShapingController
-	DoCheck(resStat base.StatNode, acquireCount uint32, threshold float64) *base.TokenResult
+	DoCheck(resStat base.StatNode, batchCount uint32, threshold float64) *base.TokenResult
 }
 
 // standaloneStatistic indicates the independent statistic for each TrafficShapingController
@@ -57,7 +57,7 @@ func (t *TrafficShapingController) FlowCalculator() TrafficShapingCalculator {
 	return t.flowCalculator
 }
 
-func (t *TrafficShapingController) PerformChecking(resStat base.StatNode, acquireCount uint32, flag int32) *base.TokenResult {
-	allowedTokens := t.flowCalculator.CalculateAllowedTokens(acquireCount, flag)
-	return t.flowChecker.DoCheck(resStat, acquireCount, allowedTokens)
+func (t *TrafficShapingController) PerformChecking(resStat base.StatNode, batchCount uint32, flag int32) *base.TokenResult {
+	allowedTokens := t.flowCalculator.CalculateAllowedTokens(batchCount, flag)
+	return t.flowChecker.DoCheck(resStat, batchCount, allowedTokens)
 }
diff --git a/core/hotspot/slot.go b/core/hotspot/slot.go
index 39cbe8f..769330d 100644
--- a/core/hotspot/slot.go
+++ b/core/hotspot/slot.go
@@ -88,7 +88,7 @@ func matchArg(tc TrafficShapingController, args []interface{}) interface{} {
 func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 	res := ctx.Resource.Name()
 	args := ctx.Input.Args
-	acquire := int64(ctx.Input.AcquireCount)
+	batch := int64(ctx.Input.BatchCount)
 
 	result := ctx.RuleCheckResult
 	tcs := getTrafficControllersFor(res)
@@ -101,7 +101,7 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 		if arg == nil {
 			continue
 		}
-		r := canPassCheck(tc, arg, acquire)
+		r := canPassCheck(tc, arg, batch)
 		if r == nil {
 			continue
 		}
@@ -119,10 +119,10 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 	return result
 }
 
-func canPassCheck(tc TrafficShapingController, arg interface{}, acquire int64) *base.TokenResult {
-	return canPassLocalCheck(tc, arg, acquire)
+func canPassCheck(tc TrafficShapingController, arg interface{}, batch int64) *base.TokenResult {
+	return canPassLocalCheck(tc, arg, batch)
 }
 
-func canPassLocalCheck(tc TrafficShapingController, arg interface{}, acquire int64) *base.TokenResult {
-	return tc.PerformChecking(arg, acquire)
+func canPassLocalCheck(tc TrafficShapingController, arg interface{}, batch int64) *base.TokenResult {
+	return tc.PerformChecking(arg, batch)
 }
diff --git a/core/hotspot/traffic_shaping.go b/core/hotspot/traffic_shaping.go
index 6726692..8ef9023 100644
--- a/core/hotspot/traffic_shaping.go
+++ b/core/hotspot/traffic_shaping.go
@@ -13,7 +13,7 @@ import (
 )
 
 type TrafficShapingController interface {
-	PerformChecking(arg interface{}, acquireCount int64) *base.TokenResult
+	PerformChecking(arg interface{}, batchCount int64) *base.TokenResult
 
 	BoundParamIndex() int
 
@@ -119,7 +119,7 @@ func (c *baseTrafficShapingController) BoundParamIndex() int {
 	return c.paramIndex
 }
 
-func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquireCount int64) *base.TokenResult {
+func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, batchCount int64) *base.TokenResult {
 	metric := c.metric
 	if metric == nil {
 		return nil
@@ -148,8 +148,8 @@ func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquir
 			fmt.Sprintf("arg=%v", arg), c.BoundRule(), nil)
 	}
 	maxCount := tokenCount + c.burstCount
-	if acquireCount > maxCount {
-		// return blocked because the acquired number is more than max count of rejectTrafficShapingController
+	if batchCount > maxCount {
+		// return blocked because the batch number is more than max count of rejectTrafficShapingController
 		return base.NewTokenResultBlockedWithCause(base.BlockTypeHotSpotParamFlow,
 			fmt.Sprintf("arg=%v", arg), c.BoundRule(), nil)
 	}
@@ -159,7 +159,7 @@ func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquir
 		lastAddTokenTimePtr := timeCounter.AddIfAbsent(arg, &currentTimeInMs)
 		if lastAddTokenTimePtr == nil {
 			// First to fill token, and consume token immediately
-			leftCount := maxCount - acquireCount
+			leftCount := maxCount - batchCount
 			tokenCounter.AddIfAbsent(arg, &leftCount)
 			return nil
 		}
@@ -168,7 +168,7 @@ func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquir
 		passTime := currentTimeInMs - atomic.LoadInt64(lastAddTokenTimePtr)
 		if passTime > c.durationInSec*1000 {
 			// Refill the tokens because statistic window has passed.
-			leftCount := maxCount - acquireCount
+			leftCount := maxCount - batchCount
 			oldQpsPtr := tokenCounter.AddIfAbsent(arg, &leftCount)
 			if oldQpsPtr == nil {
 				// Might not be accurate here.
@@ -180,9 +180,9 @@ func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquir
 				toAddTokenNum := passTime * tokenCount / (c.durationInSec * 1000)
 				newQps := int64(0)
 				if toAddTokenNum+restQps > maxCount {
-					newQps = maxCount - acquireCount
+					newQps = maxCount - batchCount
 				} else {
-					newQps = toAddTokenNum + restQps - acquireCount
+					newQps = toAddTokenNum + restQps - batchCount
 				}
 				if newQps < 0 {
 					return base.NewTokenResultBlockedWithCause(base.BlockTypeHotSpotParamFlow,
@@ -195,13 +195,13 @@ func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquir
 				runtime.Gosched()
 			}
 		} else {
-			//check whether the rest of token is enough to acquire
+			//check whether the rest of token is enough to batch
 			oldQpsPtr, found := tokenCounter.Get(arg)
 			if found {
 				oldRestToken := atomic.LoadInt64(oldQpsPtr)
-				if oldRestToken-acquireCount >= 0 {
+				if oldRestToken-batchCount >= 0 {
 					//update
-					if atomic.CompareAndSwapInt64(oldQpsPtr, oldRestToken, oldRestToken-acquireCount) {
+					if atomic.CompareAndSwapInt64(oldQpsPtr, oldRestToken, oldRestToken-batchCount) {
 						return nil
 					}
 				} else {
@@ -214,7 +214,7 @@ func (c *rejectTrafficShapingController) PerformChecking(arg interface{}, acquir
 	}
 }
 
-func (c *throttlingTrafficShapingController) PerformChecking(arg interface{}, acquireCount int64) *base.TokenResult {
+func (c *throttlingTrafficShapingController) PerformChecking(arg interface{}, batchCount int64) *base.TokenResult {
 	metric := c.metric
 	if metric == nil {
 		return nil
@@ -242,7 +242,7 @@ func (c *throttlingTrafficShapingController) PerformChecking(arg interface{}, ac
 		return base.NewTokenResultBlockedWithCause(base.BlockTypeHotSpotParamFlow,
 			fmt.Sprintf("arg=%v", arg), c.BoundRule(), nil)
 	}
-	intervalCostTime := int64(math.Round(float64(acquireCount * c.durationInSec * 1000 / tokenCount)))
+	intervalCostTime := int64(math.Round(float64(batchCount * c.durationInSec * 1000 / tokenCount)))
 	for {
 		currentTimeInMs := int64(util.CurrentTimeMillis())
 		lastPassTimePtr := timeCounter.AddIfAbsent(arg, &currentTimeInMs)
diff --git a/core/isolation/slot.go b/core/isolation/slot.go
index b202ed8..43ff0aa 100644
--- a/core/isolation/slot.go
+++ b/core/isolation/slot.go
@@ -27,7 +27,7 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 
 func checkPass(ctx *base.EntryContext) (bool, *Rule, uint32) {
 	statNode := ctx.StatNode
-	acquireCount := ctx.Input.AcquireCount
+	batchCount := ctx.Input.BatchCount
 	curCount := uint32(0)
 	for _, rule := range getRulesOfResource(ctx.Resource.Name()) {
 		threshold := rule.Threshold
@@ -38,7 +38,7 @@ func checkPass(ctx *base.EntryContext) (bool, *Rule, uint32) {
 				curCount = 0
 				logging.Error(errors.New("negative concurrency"), "", "rule", rule)
 			}
-			if curCount+acquireCount > threshold {
+			if curCount+batchCount > threshold {
 				return false, rule, curCount
 			}
 		}
diff --git a/core/log/metric/writer.go b/core/log/metric/writer.go
index ef640d8..f598248 100644
--- a/core/log/metric/writer.go
+++ b/core/log/metric/writer.go
@@ -5,6 +5,7 @@ import (
 	"encoding/binary"
 	"fmt"
 	"os"
+	"path/filepath"
 	"strconv"
 	"strings"
 	"sync"
@@ -195,7 +196,7 @@ func (d *DefaultMetricLogWriter) nextFileNameOfTime(time uint64) (string, error)
 		return "", err
 	}
 	if len(list) == 0 {
-		return d.baseDir + filePattern, nil
+		return filepath.Join(d.baseDir, filePattern), nil
 	}
 	last := list[len(list)-1]
 	var n uint32 = 0
@@ -206,7 +207,7 @@ func (d *DefaultMetricLogWriter) nextFileNameOfTime(time uint64) (string, error)
 			n = uint32(v)
 		}
 	}
-	return fmt.Sprintf("%s%s.%d", d.baseDir, filePattern, n+1), nil
+	return filepath.Join(d.baseDir, fmt.Sprintf("%s.%d", filePattern, n+1)), nil
 }
 
 func (d *DefaultMetricLogWriter) closeCurAndNewFile(filename string) error {
@@ -286,7 +287,7 @@ func NewDefaultMetricLogWriterOfApp(maxSize uint64, maxFileAmount uint32, appNam
 	if len(logDir) == 0 {
 		logDir = config.GetDefaultLogDir()
 	}
-	baseDir := util.AddPathSeparatorIfAbsent(logDir)
+	baseDir := logDir
 	baseFilename := FormMetricFileName(appName, config.LogUsePid())
 
 	writer := &DefaultMetricLogWriter{
diff --git a/core/stat/base/leap_array.go b/core/stat/base/leap_array.go
index a49fa07..97195af 100644
--- a/core/stat/base/leap_array.go
+++ b/core/stat/base/leap_array.go
@@ -201,7 +201,7 @@ func (la *LeapArray) calculateTimeIdx(now uint64) int {
 	return int(timeId) % la.array.length
 }
 
-//  Get all BucketWrap between [current time -1000ms, current time]
+//  Get all BucketWrap between [current time - leap array interval, current time]
 func (la *LeapArray) Values() []*BucketWrap {
 	return la.valuesWithTime(util.CurrentTimeMillis())
 }
diff --git a/core/stat/stat_slot.go b/core/stat/stat_slot.go
index dfa085b..d02e3c2 100644
--- a/core/stat/stat_slot.go
+++ b/core/stat/stat_slot.go
@@ -9,25 +9,25 @@ type Slot struct {
 }
 
 func (s *Slot) OnEntryPassed(ctx *base.EntryContext) {
-	s.recordPassFor(ctx.StatNode, ctx.Input.AcquireCount)
+	s.recordPassFor(ctx.StatNode, ctx.Input.BatchCount)
 	if ctx.Resource.FlowType() == base.Inbound {
-		s.recordPassFor(InboundNode(), ctx.Input.AcquireCount)
+		s.recordPassFor(InboundNode(), ctx.Input.BatchCount)
 	}
 }
 
 func (s *Slot) OnEntryBlocked(ctx *base.EntryContext, blockError *base.BlockError) {
-	s.recordBlockFor(ctx.StatNode, ctx.Input.AcquireCount)
+	s.recordBlockFor(ctx.StatNode, ctx.Input.BatchCount)
 	if ctx.Resource.FlowType() == base.Inbound {
-		s.recordBlockFor(InboundNode(), ctx.Input.AcquireCount)
+		s.recordBlockFor(InboundNode(), ctx.Input.BatchCount)
 	}
 }
 
 func (s *Slot) OnCompleted(ctx *base.EntryContext) {
 	rt := util.CurrentTimeMillis() - ctx.StartTime()
 	ctx.PutRt(rt)
-	s.recordCompleteFor(ctx.StatNode, ctx.Input.AcquireCount, rt, ctx.Err())
+	s.recordCompleteFor(ctx.StatNode, ctx.Input.BatchCount, rt, ctx.Err())
 	if ctx.Resource.FlowType() == base.Inbound {
-		s.recordCompleteFor(InboundNode(), ctx.Input.AcquireCount, rt, ctx.Err())
+		s.recordCompleteFor(InboundNode(), ctx.Input.BatchCount, rt, ctx.Err())
 	}
 }
 
diff --git a/example/isolation/concurrency_limitation_example.go b/example/isolation/concurrency_limitation_example.go
index c1bc57e..e738ce1 100644
--- a/example/isolation/concurrency_limitation_example.go
+++ b/example/isolation/concurrency_limitation_example.go
@@ -38,7 +38,7 @@ func main() {
 	for i := 0; i < 15; i++ {
 		go func() {
 			for {
-				e, b := sentinel.Entry("abc", sentinel.WithAcquireCount(1))
+				e, b := sentinel.Entry("abc", sentinel.WithBatchCount(1))
 				if b != nil {
 					logging.Info("blocked", "reason", b.BlockType().String(), "rule", b.TriggeredRule(), "snapshot", b.TriggeredValue())
 					time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)
diff --git a/logging/logging.go b/logging/logging.go
index eddc397..dedcc3a 100644
--- a/logging/logging.go
+++ b/logging/logging.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"log"
 	"os"
+	"path/filepath"
 	"runtime"
 	"strings"
 	"sync"
@@ -25,10 +26,13 @@ const (
 const (
 	// RecordLogFileName represents the default file name of the record log.
 	RecordLogFileName = "sentinel-record.log"
-	DefaultDirName    = "logs" + string(os.PathSeparator) + "csp" + string(os.PathSeparator)
 	GlobalCallerDepth = 4
 )
 
+var (
+	DefaultDirName = filepath.Join("logs", "csp")
+)
+
 var (
 	globalLogLevel = InfoLevel
 	globalLogger   = NewConsoleLogger()
diff --git a/util/file.go b/util/file.go
index e8aec50..73fcc9c 100644
--- a/util/file.go
+++ b/util/file.go
@@ -4,7 +4,6 @@ import (
 	"errors"
 	"io"
 	"os"
-	"strings"
 )
 
 func FilePosition(file *os.File) (int64, error) {
@@ -34,11 +33,3 @@ func CreateDirIfNotExists(dirname string) error {
 	}
 	return nil
 }
-
-func AddPathSeparatorIfAbsent(path string) string {
-	s := string(os.PathSeparator)
-	if !strings.HasSuffix(path, s) {
-		return path + s
-	}
-	return path
-}


Test patch:
diff --git a/api/api_test.go b/api/api_test.go
index 1ef683f..ea0d6e0 100644
--- a/api/api_test.go
+++ b/api/api_test.go
@@ -72,7 +72,7 @@ func Test_entryWithArgsAndChainPass(t *testing.T) {
 	entry, b := entry("abc", &EntryOptions{
 		resourceType: base.ResTypeCommon,
 		entryType:    base.Inbound,
-		acquireCount: 1,
+		batchCount:   1,
 		flag:         0,
 		slotChain:    sc,
 	})
@@ -112,7 +112,7 @@ func Test_entryWithArgsAndChainBlock(t *testing.T) {
 	entry, b := entry("abc", &EntryOptions{
 		resourceType: base.ResTypeCommon,
 		entryType:    base.Inbound,
-		acquireCount: 1,
+		batchCount:   1,
 		flag:         0,
 		slotChain:    sc,
 	})
diff --git a/core/base/slot_chain_test.go b/core/base/slot_chain_test.go
index 645c936..4b13d40 100644
--- a/core/base/slot_chain_test.go
+++ b/core/base/slot_chain_test.go
@@ -223,10 +223,10 @@ func TestSlotChain_Entry_Pass_And_Exit(t *testing.T) {
 	ctx.SetEntry(NewSentinelEntry(ctx, rw, sc))
 	ctx.StatNode = &StatNodeMock{}
 	ctx.Input = &SentinelInput{
-		AcquireCount: 1,
-		Flag:         0,
-		Args:         nil,
-		Attachments:  nil,
+		BatchCount:  1,
+		Flag:        0,
+		Args:        nil,
+		Attachments: nil,
 	}
 
 	ps1 := &prepareSlotMock{}
@@ -266,10 +266,10 @@ func TestSlotChain_Entry_Block(t *testing.T) {
 	ctx.Resource = rw
 	ctx.StatNode = &StatNodeMock{}
 	ctx.Input = &SentinelInput{
-		AcquireCount: 1,
-		Flag:         0,
-		Args:         nil,
-		Attachments:  nil,
+		BatchCount:  1,
+		Flag:        0,
+		Args:        nil,
+		Attachments: nil,
 	}
 
 	rbs := &prepareSlotMock{}
@@ -324,10 +324,10 @@ func TestSlotChain_Entry_With_Panic(t *testing.T) {
 	statNodeMock.On("AddErrorRequest", mock.Anything).Return()
 	ctx.StatNode = statNodeMock
 	ctx.Input = &SentinelInput{
-		AcquireCount: 1,
-		Flag:         0,
-		Args:         nil,
-		Attachments:  nil,
+		BatchCount:  1,
+		Flag:        0,
+		Args:        nil,
+		Attachments: nil,
 	}
 
 	rbs := &badPrepareSlotMock{}
diff --git a/core/flow/slot_test.go b/core/flow/slot_test.go
index fda8981..bceb9a2 100644
--- a/core/flow/slot_test.go
+++ b/core/flow/slot_test.go
@@ -18,7 +18,7 @@ func Test_FlowSlot_StandaloneStat(t *testing.T) {
 		Resource: res,
 		StatNode: resNode,
 		Input: &base.SentinelInput{
-			AcquireCount: 1,
+			BatchCount: 1,
 		},
 		RuleCheckResult: nil,
 		Data:            nil,
diff --git a/core/hotspot/slot_test.go b/core/hotspot/slot_test.go
index 658b902..e837cc0 100644
--- a/core/hotspot/slot_test.go
+++ b/core/hotspot/slot_test.go
@@ -15,8 +15,8 @@ type TrafficShapingControllerMock struct {
 	mock.Mock
 }
 
-func (m *TrafficShapingControllerMock) PerformChecking(arg interface{}, acquireCount int64) *base.TokenResult {
-	retArgs := m.Called(arg, acquireCount)
+func (m *TrafficShapingControllerMock) PerformChecking(arg interface{}, batchCount int64) *base.TokenResult {
+	retArgs := m.Called(arg, batchCount)
 	return retArgs.Get(0).(*base.TokenResult)
 }
 
diff --git a/core/stat/base/leap_array_test.go b/core/stat/base/leap_array_test.go
index a2e5a4d..fff92a2 100644
--- a/core/stat/base/leap_array_test.go
+++ b/core/stat/base/leap_array_test.go
@@ -28,7 +28,7 @@ func Test_bucketWrapper_Size(t *testing.T) {
 		t.Errorf("the size of BucketWrap is not equal 24.\n")
 	}
 	if unsafe.Sizeof(ww) != 8 {
-		t.Errorf("the size of BucketWrap is not equal 24.\n")
+		t.Errorf("the size of BucketWrap pointer is not equal 8.\n")
 	}
 }