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

Clarify Equality #765

Open
no-reply opened this issue Oct 17, 2019 · 6 comments
Open

Clarify Equality #765

no-reply opened this issue Oct 17, 2019 · 6 comments

Comments

@no-reply
Copy link
Contributor

no-reply commented Oct 17, 2019

Equality is currently based on the default Dry::Struct implementation, which compares all ResourceClass.__attributes__ . This includes ::Valkyrie::Persistence::OptimisticLockToken, which should likely be excluded.

We may want to consider excluding other reserved attributes.

class ResourceWithLock < Valkyrie::Resource)
  enable_optimistic_locking
end

resource1 = ResourceWithLock(id: 'blah', Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => Valkyrie::Persistence::OptimisticLockToken.deserialize('lock_token:test:1'))
resource2 = ResourceWithLock(id: 'blah', Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => Valkyrie::Persistence::OptimisticLockToken.deserialize('lock_token:test:2'))

resource1 == resource2 # => false
@no-reply
Copy link
Contributor Author

One approach to this issue is to move the optimistic lock token out of #attributes.

That probably constitutes a major release, and might involve a bit of work since there's some use of the Dry::Types, but my intuition is that it's the best approach.

@escowles
Copy link
Contributor

It looks like both Memory and Fedora are using the current Time of the object's instantiation to create the lock tokens:

@tpendragon
Copy link
Collaborator

tpendragon commented Oct 17, 2019

The other option is we just change equality to be something like AR, where if it's persisted it == if the two share an ID/class (thanks @jrochkind for digging that up)

@no-reply
Copy link
Contributor Author

i'll express a preference for Dry::Struct-style equality. it seems so easy to do ID equality as a client that using #== for it seems wasteful. resource.id == other.id

for reference: include Dry::Equalizer(:id) ought to be all it takes to implement #== as AR-style ID equality; including the class check.

@tpendragon
Copy link
Collaborator

I'm having a hard time figuring out how we can move this forward. I think I need some use cases where I want two things to be equal to one another if they have different lock tokens.

@no-reply
Copy link
Contributor Author

no-reply commented Oct 19, 2021

@tpendragon: if i recall, the motivating need here was Sets. for example, i think the behavior of the following code varies depending on otherwise irrelevant details of the adapters optimistic locking behavior:

class Permission < Valkyrie::Resource
  enable_optimistic_locking
  attribute :mode
  attribute :user
end

class ResourceWithPermissions < Valkyrie::Resource
  enable_optimistic_locking
  attribute :permissions, Valkyrie::Types::Set.of(Permission)
end

p = Permission.new(mode: :read, user: 'user_key')
p = Valkyrie.config.metadata_adapter.persister.save(resource: p)

resource = ResourceWithPermissions.new(permissions: [p])

p2 = Valkyrie.config.metadata_adapter.query_service.find_by(id: p.id)
resource.permissions << p2

a practical example exists in Hyrax: https://github.com/samvera/hyrax/blob/f8706bc91d1caa3a4cdd73401cc7d081ec158437/app/models/hyrax/permission.rb#L13

but honestly, i think it would be desirable as a matter of principle for Valkyrie.config.metadata_adapter.query.find_by(id: 'some_id') == Valkyrie.config.metadata_adapter.query.find_by(id: 'some_id') to be true for all adapters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

No branches or pull requests

3 participants