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

Fix/issue 684 #820

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

Phoenix500526
Copy link
Collaborator

@Phoenix500526 Phoenix500526 commented May 15, 2024

Please briefly answer these questions:
Close the issue #664 and #684

@mergify mergify bot requested a review from a team May 15, 2024 12:43
Copy link

mergify bot commented May 15, 2024

@Phoenix500526 Convert your pr to draft since CI failed

@mergify mergify bot marked this pull request as draft May 15, 2024 12:44
@mergify mergify bot added the CI:fail CI has failed label May 15, 2024
Copy link

mergify bot commented May 15, 2024

@Phoenix500526 You've modified the workflows. Please don't forget to update the .mergify.yml.

@mergify mergify bot marked this pull request as ready for review May 15, 2024 13:19
@mergify mergify bot removed the CI:fail CI has failed label May 15, 2024
Copy link

codecov bot commented May 15, 2024

Codecov Report

Attention: Patch coverage is 70.04831% with 62 lines in your changes missing coverage. Please review.

Project coverage is 75.62%. Comparing base (e35b35a) to head (32fa940).
Report is 123 commits behind head on master.

Files Patch % Lines
crates/xline-client/src/clients/lock.rs 73.97% 38 Missing and 13 partials ⚠️
crates/xlinectl/src/command/lock.rs 0.00% 6 Missing ⚠️
crates/xlinectl/src/command/lease/keep_alive.rs 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #820      +/-   ##
==========================================
+ Coverage   75.55%   75.62%   +0.07%     
==========================================
  Files         180      185       +5     
  Lines       26938    27761     +823     
  Branches    26938    27761     +823     
==========================================
+ Hits        20353    20995     +642     
- Misses       5366     5469     +103     
- Partials     1219     1297      +78     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

crates/xline-client/examples/lock.rs Outdated Show resolved Hide resolved
crates/xline-client/src/clients/lock.rs Outdated Show resolved Hide resolved
};
let mut lease_client = self.client.lease_client.clone();
let lease_id = self.lease_id;
self.keep_alive = Some(tokio::spawn(async move {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we notify the user if the keep alive task exit before unlock?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It seems we can do nothing but panic. Do you have any better solutions?

Copy link
Collaborator

Choose a reason for hiding this comment

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

On second thought, I think it's impossible to make sure that the lock is always held during crital section, the user must assume the lock is held.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Shall we still need to handle this problem if it's impossible to make sure that the lock is always held during critical section?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we could simply print an error message when the task exits.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We may consider implementing this #820 (comment)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Currently, a user will get an error when he invokes the lock method on a Xutex of which keep-alive task exists.

Copy link
Collaborator

@bsbds bsbds Jun 21, 2024

Choose a reason for hiding this comment

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

I suggest to use the following API to avoid confusion about how to use the lock:

    let xutex = Xutex::new(..).await?;
    xutex.put(..).await?;
    xutex.range(..).await?;
    xutex.delete_range(..).await?;
    xutex.txn(..).await?;

    let guard = xutex.lock_unsafe().await?;
    // perform some unsafe operation that may break consistency
    // ...
    drop(guard);

We could directly implement safe operations put/range/delete_range/txn for the type Xutex, and also implement a lock_unsafe method to make it compatible with the behavior of the etcd client.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What does ‘compatible with the behavior of the etcd client’ mean? Just renaming lock as lock_unsafe? In addition, I don't get the point why implementing put/range/delete_range is less confusing than not implementing them? The Xutex is a lock wrapper, not a KvClient wrapper. Therefore, if a user needs to do something while holding a lock, he should use a KvClient to initiate a request instead of using Xutex. Considering that, I think providing txn_with_locked_key is enough. What it does is only to generate a txn request which compares the locked key exist or not.

crates/xline-client/tests/it/lock.rs Outdated Show resolved Hide resolved
crates/xlinectl/src/command/lock.rs Outdated Show resolved Hide resolved
crates/xline-client/src/clients/lock.rs Outdated Show resolved Hide resolved
@mergify mergify bot requested a review from a team May 17, 2024 02:05
Copy link

mergify bot commented May 17, 2024

@Phoenix500526 Convert your pr to draft since CI failed

@mergify mergify bot marked this pull request as draft May 17, 2024 07:33
@mergify mergify bot added the CI:fail CI has failed label May 17, 2024
@Phoenix500526 Phoenix500526 force-pushed the fix/issue-684 branch 2 times, most recently from 1c973bf to dcc89ca Compare May 17, 2024 08:20
@mergify mergify bot marked this pull request as ready for review May 17, 2024 08:31
@mergify mergify bot removed the CI:fail CI has failed label May 17, 2024
Copy link

mergify bot commented May 20, 2024

@Phoenix500526 Your PR is in conflict and cannot be merged.

@mergify mergify bot requested a review from a team May 21, 2024 07:49
Copy link

mergify bot commented May 22, 2024

@Phoenix500526 Your PR is in conflict and cannot be merged.

Copy link
Collaborator

@rogercloud rogercloud left a comment

Choose a reason for hiding this comment

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

Mutex and its guard may be not the best way to abstract. If there's any error happens, such as lease renew failure, lock free is a good point to report error. In the mutex guard abstraction, lock free is in the drop function, which is not possible to handle for the caller.

crates/xline-client/src/clients/lock.rs Outdated Show resolved Hide resolved

/// An RAII implementation of a “scoped lock” of an `Xutex`
#[derive(Default, Debug)]
pub struct XutexGuard {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Usually mutex guards have a lifetime bound, make sure the mutex itself lives longer than the guards. Shall we follow it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The async_dropper requires the Default trait. If we introduce the lifetime bound for XutexGuard, the async_dropper may not work properly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

How about we allow the user to do a manual unlock, and the unlock could return some information to the user.
For example:

{
    enum UnlockResult {
        Ok,
        // The lock may has been unlocked by the server
        Unsafe(Err),
    }
    let guard = xutex.lock_unsafe().await?;
    let result: UnlockResult = guard.unlock().await?;
    match result {
        // handles the lock result
        // ...
    }
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Manually unlocking may not be a good practice since the likelihood of a user forgetting to unlock is greater than the likelihood of a panic occurring.

crates/xline-client/src/clients/lock.rs Outdated Show resolved Hide resolved
crates/xline-client/src/clients/lock.rs Show resolved Hide resolved
crates/xline-client/examples/lock.rs Outdated Show resolved Hide resolved
@mergify mergify bot requested a review from a team May 22, 2024 16:13
@Phoenix500526
Copy link
Collaborator Author

Mutex and its guard may be not the best way to abstract. If there's any error happens, such as lease renew failure, lock free is a good point to report error. In the mutex guard abstraction, lock free is in the drop function, which is not possible to handle for the caller.

But if you don't provide an RAII implementation for the lock, users may be bothered by the fact that they may forget to free a lock.

@rogercloud
Copy link
Collaborator

rogercloud commented May 30, 2024

Mutex and its guard may be not the best way to abstract. If there's any error happens, such as lease renew failure, lock free is a good point to report error. In the mutex guard abstraction, lock free is in the drop function, which is not possible to handle for the caller.

But if you don't provide an RAII implementation for the lock, users may be bothered by the fact that they may forget to free a lock.

No, they won't if you put operations dealing with the locked data in a closure and release the lock while leaving the closure. For example providing the following code:

let return_value = a_xutex.map_lock( |xutex_guard| {
/// dealing with the guard
});

The return_value can tell if there's any lock related issue during the closure.

Additionally if you follow this way, the life time bound of the guard is not necessary as there's only one way to get the guard and drop it.

Copy link

mergify bot commented Jun 9, 2024

@Phoenix500526 Convert your pr to draft since CI failed

@mergify mergify bot marked this pull request as draft June 9, 2024 03:26
@mergify mergify bot added the CI:fail CI has failed label Jun 9, 2024
@Phoenix500526 Phoenix500526 force-pushed the fix/issue-684 branch 2 times, most recently from 70d0524 to 7decae5 Compare June 11, 2024 06:32
@mergify mergify bot marked this pull request as ready for review June 11, 2024 06:41
@mergify mergify bot removed the CI:fail CI has failed label Jun 11, 2024
Copy link

mergify bot commented Jun 13, 2024

@Phoenix500526 Your PR is in conflict and cannot be merged.

Copy link

mergify bot commented Jun 18, 2024

@Phoenix500526 Convert your pr to draft since CI failed

@mergify mergify bot marked this pull request as draft June 18, 2024 02:12
@mergify mergify bot added the CI:fail CI has failed label Jun 18, 2024
@mergify mergify bot marked this pull request as ready for review June 18, 2024 02:24
@mergify mergify bot removed the CI:fail CI has failed label Jun 18, 2024
@bsbds
Copy link
Collaborator

bsbds commented Jun 18, 2024

We could guarantee the lock safety by coupling the lock key to every update send to Xline, and the Xline server must verify the validity of the key. Please refer to https://jepsen.io/analyses/etcd-3.4.3

On the client side, we could associate KV operation methods to the lock guard to prevent user from using the lock for other purpose.

@Phoenix500526
Copy link
Collaborator Author

@Mergifyio rebase

Closes: xline-kv#664
Signed-off-by: Phoeniix Zhao <Phoenix500526@163.com>
Closes: 664,684
Signed-off-by: Phoeniix Zhao <Phoenix500526@163.com>
Signed-off-by: Phoeniix Zhao <Phoenix500526@163.com>
Copy link

mergify bot commented Jun 18, 2024

rebase

✅ Branch has been successfully rebased

Copy link
Collaborator

@CrystalAnalyst CrystalAnalyst left a comment

Choose a reason for hiding this comment

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

LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants