Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow concurrent calls for Fake methods. #16

Merged
merged 1 commit into from
Sep 9, 2024

Conversation

npinaeva
Copy link
Member

@npinaeva npinaeva commented Sep 2, 2024

Before, calling fake.Run and fake.Dump from different goroutines caused a data race.

@k8s-ci-robot k8s-ci-robot requested a review from aojea September 2, 2024 08:03
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Sep 2, 2024
@k8s-ci-robot k8s-ci-robot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Sep 2, 2024
Copy link
Collaborator

@danwinship danwinship left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I'm surprised we didn't run into this already...

fake.go Outdated
)

// Fake is a fake implementation of Interface
type Fake struct {
nftContext
// lock is used to protect Table and LastTransaction.
// When Table and LastTransaction are accessed directly, it is caller's responsibility
// to ensure there is no data race.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's no good... should probably make them private members, and add accessors for them that do proper locking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to break existing users, but if you think it is ok, I can make them private

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

later discussed on slack; just adding accessors doesn't work because you'd have to deep-copy Table. So maybe it would make more sense to expose the locking to the caller. Make the sync.Mutex an embedded field like the nftContext, and document the fact that you need to .RLock() it if you are going to look directly at Table.

Maybe .LastTransaction should be changed to .GetLastTransaction() though, with locking. (The transaction itself would be read-only at this point, so you don't have to worry about locking after you access the pointer.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made lock methods external, added little comments

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I like that idea of GetLastTransaction because it

  1. is inconsistent with Table access, which is a bit strange
  2. will limit potential changes in the future if we ever need to make LastTransaction not-read-only.
    wdyt?

fake.go Outdated
)

// Fake is a fake implementation of Interface
type Fake struct {
nftContext
// mutex is used to protect Table and LastTransaction.
// When Table and LastTransaction are accessed directly, the caller must acquire Fake.Rlock
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// When Table and LastTransaction are accessed directly, the caller must acquire Fake.Rlock
// When Table and LastTransaction are accessed directly, the caller must acquire Fake.RLock

and below

fake.go Outdated
Comment on lines 46 to 47
// Make sure to acquire Fake.Rlock before accessing Table in a concurrent environment.
LastTransaction *Transaction
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Make sure to acquire Fake.Rlock before accessing Table in a concurrent environment.
LastTransaction *Transaction
// Make sure to acquire Fake.Rlock before accessing LastTransaction in a concurrent environment.
LastTransaction *Transaction

But that feels wrong anyway... LastTransaction is inherently non-concurrency-safe; you can only know that it has the transaction you want if you already know for sure what the most recent Run() call was. So maybe just add a warning about that. "This is probably not useful if Interface is being used concurrently." ?

And I guess that's an argument against GetLastTransaction().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may be useful for concurrent usage also.
Let's say there is a controller thread running transactions, and test thread checking if it is correct.
On every change I make explicitly in the test, controller is expected to make exactly one transaction, but it may take time to reconcile. I will periodically check from the test thread LastTransaction until I see expected transaction, but to make it non-racy, I need to make sure I have RLock while reading LastTransaction.

@danwinship
Copy link
Collaborator

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 9, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: danwinship, npinaeva

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 9, 2024
@k8s-ci-robot k8s-ci-robot merged commit 52e5579 into kubernetes-sigs:master Sep 9, 2024
5 checks passed
@npinaeva npinaeva deleted the fake-lock branch September 10, 2024 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants