-
Notifications
You must be signed in to change notification settings - Fork 124
Proposed High Level Outline for Deprecating the ActorStack
The goal of this refactor is to remove the case logic around the create_work
and update_work
methods in the Hyrax::WorksControllerBehavior
module. Aspirationally, we would factor away the actor stack in favor of a form and transaction.
Below is an example of the two logic paths, one for ActiveFedora::Base
objects and one for everything elses (e.g. Valkyrie
objects).
# See ./app/controllers/concerns/hyrax/works_controller_behavior.rb
def create_work
case curation_concern
when ActiveFedora::Base
# I copied the following two lines to provide more context for the example
actor_environment = Actors::Environment.new(curation_concern, current_ability, attributes_for_actor)
actor = Hyrax::CurationConcern.actor
actor.create(actor_environment)
else
# I copied the following two lines to provide more context for the example
transactions = Hyrax::Transactions::Container
form = work_form_service.build(curation_concern, current_ability, self)
@curation_concern = form.validate(params[hash_key_for_curation_concern]) &&
transactions['change_set.create_work'].call(form).value!
end
end
For ActiveFedora::Base
we build the actor_environment
, analogue to Rack middleware’s env
. With that environment we tell the actor to perform a create
. The actor is responsible for both data validation and performing any other state changing processes.
Multiple actors compose the stack (see ./app/services/hyrax/default_middleware_stack.rb
). Each actor implements a create
and update
method that receives the actor_environment
.
The pattern of each actor is as follows: validate && next_actor.act && do_something
.
- Validates the given actor environment based on the current actor’s “area of focus”
- Add errors if not valid
- If valid, calls the next step in the actor stack
- If the called next step is true, perform state changing operations based on “area of focus”
With multiple actors in the stack, as we work our way down the stack, we stop at the first encountered error.
If we work our way down to the bottom of the stack, without errors, we begin applying state changing operations as we traverse back up the stack. During this process we hope to not encounter errors/exceptions, as this will leave our data in a partially changed state (e.g. we have minimal transactionality).
For the other case (e.g. not ActiveFedora::Base
), we separate the validations (e.g. form.validate
)from the state changing operations (e.g. transactions[‘change_set.create_work’].call(form)
).
Aspirationally, we want the form.validate
to perform the same-ish validations as the actor stack steps. Likewise, when we use the named transaction (e.g. transactions[‘change_set.create_work’]
) we want to perform the same-ish state changing processes as the actor stack steps.
From ./app/services/hyrax/default_middleware_stack.rb
we have the following actors:
Hyrax::Actors::OptimisticLockValidator
Hyrax::Actors::CreateWithRemoteFilesActor
Hyrax::Actors::CreateWithFilesActor
Hyrax::Actors::CollectionsMembershipActor
Hyrax::Actors::AddToWorkActor
Hyrax::Actors::AttachMembersActor
Hyrax::Actors::ApplyOrderActor
Hyrax::Actors::DefaultAdminSetActor
Hyrax::Actors::InterpretVisibilityActor
Hyrax::Actors::TransferRequestActor
Hyrax::Actors::ApplyPermissionTemplateActor
Hyrax::Actors::CleanupFileSetsActor
Hyrax::Actors::CleanupTrophiesActor
Hyrax::Actors::FeaturedWorkActor
Hyrax::Actors::ModelActor
Hyrax::Actors::InitializeWorkflowActor
These need to be teased their validations extracted into a form
object, and their state changing actions extracted into a transaction
object.