Skip to content

Possible to lost tokens in refill function #11

Description

@taras-zak

In case when ctx that passed to Effector canceled by timeout before refill ticker fires - possible lost token. Here is example:

func TestRefill(t *testing.T) {
	const max uint = 1
	const refillDuration = time.Second

	callsCounter := 0
	effector := callsCountFunction(&callsCounter)

	// Any context with cancellation (WithTimeout, etc)
	ctx, cancel := context.WithCancel(context.Background())
	throttle := Throttle(effector, max, max, refillDuration)

	_, err := throttle(ctx)
	if err != nil {
		t.Fatal("unexpected error: ", err)
	}
	if callsCounter != 1 {
		t.Fatal("unexpected callsCounter value: ", callsCounter)
	}
	// Request cancelled by timeout before refillDuration. (If comment this line – test will be success)
	cancel()

	// Waiting token refill . x2 for ensure that token refiled
	time.Sleep(refillDuration * 2)

	ctx, cancel = context.WithCancel(context.Background())
	defer cancel()

	_, err = throttle(ctx)
	if err != nil {
		t.Fatal("unexpected error: ", err)
	}
	if callsCounter != 2 {
		t.Fatal("unexpected callsCounter value: ", callsCounter)
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions