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

Update depositors (proxies, transfers) synchronously #5537

Closed
wants to merge 7 commits into from

Conversation

hackartisan
Copy link
Contributor

@hackartisan hackartisan commented Mar 15, 2022

This PR is in draft since it depends on merge of #5529. It should be rebased on main once that happens.

Follow-up to #5529
closes #5457

The ChangeContentDepositorService is where the correct depositor and
proxy_depositor values are set. the ContentDepositorChangeEventJob emits events related to depositor changes. Before this PR the service was always called by the job, which ran the service before emitting the related events. After this PR, that's flipped and the service enqueues the job after it's finished making the updates. Where the job was previously invoked, now we invoke the service.

Previous to #5529, the job (and thus the service) was called by a
listener or a callback in response to object deposit events. The changes in
#5529, intended to resolve a race condition bug, also made it easier to decouple
the AF behavior from the Valkyrie behavior, making the change in synchronous code in both cases.

Previous code state and summary of changes:

ChangeContentDepositorService was called from
  ContentDepositorChangeEventJob which is called from:

    app/models/proxy_deposit_request#transfer! (used by transfers_controller)

      - Call the depositor service instead of the change event job


    app/actors/hyrax/actors/transfer_request_actor

      - Call the depositor service instead of the change event job


    app/services/hyrax/listeners/proxy_deposit_listener
      listened for object.deposited, which is published by:

        lib/hyrax/transactions/steps/save.rb

          - Create a new transaction step to call invoke the service


        app/services/hyrax/work_uploads_handler.rb

          - I don't think the work uploads handler has any implications for
            proxy depositors so I think it's fine to leave this alone -- it can
            still publish the object.deposited message but with the proxy depositor
            listener removed I don't think there's any impact to behavior for
            this workflow.

        the after_create_concern callback, which is invoked by base_actor.rb

           - With the transfer request actor back in use, there's no impact here
             either.

Update the ChangeContentDepositorService to enqueue the ContentDepositorChangeEventJob. Update the ContentDepositorChangeEventJob to expect an work that has already been transferred, and to simply emit the required events rather than changing the objects first.

@hackartisan hackartisan marked this pull request as draft March 15, 2022 18:08
@hackartisan hackartisan changed the base branch from main to 5457-revert-proxy-deposit-listener March 15, 2022 18:14
@hackartisan hackartisan force-pushed the 5457-add-proxy-deposit-transaction-step branch from efdfaa5 to 491d022 Compare March 15, 2022 20:41
This way it only happens if the code path gets by the guards.
@hackartisan hackartisan force-pushed the 5457-add-proxy-deposit-transaction-step branch from 491d022 to c007962 Compare March 15, 2022 21:03
@hackartisan hackartisan changed the title Separate content depositor change from content depositor change event job Update depositors (proxies, transfers) synchronously Mar 15, 2022
Copy link
Contributor

@elrayle elrayle left a comment

Choose a reason for hiding this comment

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

This is looking really good. I had a couple of suggestions and a question.

def perform(work, user, reset = false)
@reset = reset
super(work, user)
# @param [ActiveFedora::Base] work the work that's been transfered
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this parameter be a Hyrax::Work (i.e., Valkyrie::Resource)?

Suggested change
# @param [ActiveFedora::Base] work the work that's been transfered
# @param [ActiveFedora::Base,Hyrax::Work] work the work that's been transferred

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes thank you

depositor.log_event(event)
end

def proxy_depositor
@proxy_depositor ||= ::User.find_by_user_key(work.proxy_depositor)
private def previous_owner
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, I haven't seen including private on the line with the method def. Has this always worked or did this start in a specific Rails version? Typically, the private keyword is on a line by itself with all methods that follow being private. In Hyrax, that is the only pattern I see in use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm not sure when. I've been thinking it would be nice to use it because it's more explicit than a private floating around somewhere in the file, especially if extra indentation isn't enforced. But it's not idiomatic; I'll change it.

# user_key is nil when there was no `on_behalf_of` in the form
return work unless user&.user_key
# Don't transfer to self
return work if user.user_key == work.depositor
Copy link
Contributor

Choose a reason for hiding this comment

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

nice to have exit checks and avoid unnecessary work

@@ -49,7 +61,6 @@ def self.call_valkyrie(work, user, reset)
apply_valkyrie_changes_to_file_sets(work: work, user: user, reset: reset)

Hyrax.persister.save(resource: work)
work
Copy link
Contributor

Choose a reason for hiding this comment

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

good catch

#
# @return [Dry::Monads::Result]
def call(obj, user: NullUser.new, reset: false)
obj = Hyrax::ChangeContentDepositorService.call(obj, user, reset)
Copy link
Contributor

Choose a reason for hiding this comment

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

should this bail if user is null?

Suggested change
obj = Hyrax::ChangeContentDepositorService.call(obj, user, reset)
return Success(obj) unless user&.user_key
obj = Hyrax::ChangeContentDepositorService.call(obj, user, reset)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the service has this guard, do you think we should do it both places?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We agreed to add it to make the code more explicit.

Base automatically changed from 5457-revert-proxy-deposit-listener to main March 16, 2022 17:07
@@ -30,18 +27,19 @@ def log_work_event(work)
end
alias log_file_set_event log_work_event

def work
@work ||= Hyrax::ChangeContentDepositorService.call(repo_object, depositor, reset)
end
Copy link
Contributor

Choose a reason for hiding this comment

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

This method call has been used for over 5 years. So it is making less sense to me now that this would be a problem. I originally thought this was moved here when the listener was created. Still not ruling out the various methods are chasing each other.

@hackartisan
Copy link
Contributor Author

superceded by #5553; code review addressed there.

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

Successfully merging this pull request may close these issues.

Works deposited via proxy are always set to private visibility
2 participants