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

Introduce LockBox for managing lock hierarchy #6

Merged
merged 1 commit into from
Apr 14, 2022
Merged

Conversation

CMCDragonkai
Copy link
Member

@CMCDragonkai CMCDragonkai commented Apr 12, 2022

Description

Implements LockBox to be used by EFS and js-polykey.

Issues Fixed

Tasks

  • 1. Integrate ideas used in EFS and PK
  • 2. Cross-domain usage combined with withF
  • 3. Filter duplicate locking to avoid deadlocks
  • 4. Add in deadlock tests to demonstrate
  • 5. Make it generic to the type of lock being used with existential types

Final checklist

  • Domain specific tests
  • Full tests
  • Updated inline-comment documentation
  • Lint fixed
  • Squash and rebased
  • Sanity check the final build

@CMCDragonkai
Copy link
Member Author

CMCDragonkai commented Apr 12, 2022

The LockBox can be used like this now:

    const lockBox = new LockBox();
    await withF(
      [
        // the extra parameters after `['1', Lock, ...params]` is typesafe to the `Lock.lock` method
        lockBox.lock(['1', Lock], ['2', Lock]),
      ],
      async ([[l1, l2]]) => {
        expect(l1.isLocked()).toBe(true);
        expect(l2.isLocked()).toBe(true);
      }
    );

The Lock class is used because LockBox doesn't know what type of lock you want.

We could specialise a "default" lock to be used in some cases though when constructing the LockBox.

Anyway this makes LockBox generic to the lock being used. Which should be usable by EFS as it will just always use Lock in its withTransactionF and withTransactionG.

For our usage in PK, we would likely instead use RWLockWriter in any withTransctionF and withTransactionG.

Further abstractions can be developed out of usage.

Note that extra parameters can be passed in:

lockBox.lock(['1', Lock, 1000]);

The extra parameters are inferred to be the parameter types of the Lockable.lock method.

I've added a lock method to all Lockable classes. Of which Lockable is an interface.

For example:

lockBox.lock(['1', RWLockWriter, 'read'])
lockBox.lock(['1', RWLockWriter, 'write'])
lockBox.lock(['1', RWLockWriter, 'write', 1000])

It's also all type safe.

If the a key is already locked by a certain class like Lock, and you give it a different class. This will throw an exception ErrorAsyncLocksLockBoxConflict. So make sure to use the same type of lock for the same set of keys.

@CMCDragonkai
Copy link
Member Author

No vertical axis or prefix trie yet. I think that can be done in the future as as separate class LockBoxTrie for more advanced locking as that has additional complexity to consider. The locking keys themselves would become arrays.

@CMCDragonkai
Copy link
Member Author

The LockBox is done. One thing that is missing is that the types don't know to match the parameter set with the relevant constructor.

For example this doesn't raise a type error:

await lockBox.lock([1, Lock, 'read'])

Ideally we were able to say that the parameters are specific to Lock.lock method. However I wasn't able to figure this out. I might ask around on SO.

@CMCDragonkai
Copy link
Member Author

Additionally I think now that we can have rest parameters in the front, I believe parameters like timeout should actually be in the front of the final callback parameter for withF and withG convenience methods.

@CMCDragonkai CMCDragonkai changed the title WIP: Introduce LockBox for managing lock hierarchy Introduce LockBox for managing lock hierarchy Apr 14, 2022
@CMCDragonkai CMCDragonkai merged commit e5b59fe into master Apr 14, 2022
@CMCDragonkai CMCDragonkai deleted the lockbox branch April 14, 2022 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

LockBox - Collection structure for managing multiple locks
1 participant