Closed (fixed)
Project:
Workspace
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
15 Jun 2016 at 14:11 UTC
Updated:
26 Aug 2016 at 14:50 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
josephdpurcell commentedComment #3
josephdpurcell commentedThis patch is a draft for implementing the ReplicationTask. There are a few @todos to follow up on during review:
Should we just create an empty ReplicationTask to pass here? If so, probably create it in "onTransition" method and pass here to "mergeWorkspaceToParent" as a parameter.
Should we just create an empty ReplicationTask to pass here?
Is the ReplicationTask needed during the "applies" method logic? If so, we should pass it in as a parameter.
Comment #4
josephdpurcell commentedComment #5
timmillwoodComment #7
timmillwoodMerged this, but still needs tests.
Comment #11
josephdpurcell commentedI have created a test for the InternalReplicator, but it is failing: https://github.com/timmillwood/drupal-workspace/pull/6
My suspicion is that I am missing a step when triggering replication.
Comment #12
timmillwoodCan I suggest using
BrowserTestBaselike https://github.com/timmillwood/drupal-workspace/blob/8.x-1.x/tests/src/F... does?The UID issue might be a deeper bug. We don't replicate users anymore, but instead try to match on UUID or username, I guess this is failing somewhere in the serializer.
Comment #13
josephdpurcell commentedHere is a patch showing the failing test. After switching to BrowserTestBase I experienced the same failure: while the entity was in fact replicated:
The validation that replication was successful fails:
I recall that there are caveats / difficulties to testing workspaces and replication (one reason for using BrowserTestBase) so I don't want to spend too much time on this test. As such I'm going to submit this for anyone to pick up and will come back to it (hopefully next week).
Comment #14
josephdpurcell commentedPatch #14 addresses this ticket and is related to #2764289: What action should Replication Filters apply to? and #2749177: Propose UI for Replication Filters.
The tests are passing on GitHub: https://github.com/timmillwood/drupal-workspace/pull/7
Here are key points of what this patch accomplishes:
Potential improvements I see would be revising the UI to follow https://www.drupal.org/node/2764289#comment-11485043 and moving the majority of ReplicationSettings test to the replication module and having the test *just* be for the Workspace form setting the ReplicationSettings entity properly.
Comment #15
josephdpurcell commentedComment #22
phenaproximaWhy have a $replication_settings flag? Why not simply do something like this:
This is pretty close to what's in WorkbenchModerationSubscriber. Can it be moved into a utility method for DRY purposes?
A bit out of scope, but the replicator_manager service should be injected if this is a form (FormBase implements ContainerInjectionInterface).
Again, this is repeating code. Can that be fixed?
Ditto here.
How $pull_log used? It doesn't look like it's ever returned or touched further in this method.
Comment #23
jeqq commented@josephdpurcell Tests are failing in Travis too: https://travis-ci.org/timmillwood/drupal-workspace/jobs/150725700
Comment #24
jeqq commented@josephdpurcell Thank you for all your awesome work on this!
Addressed all point from #22.
@josephdpurcell Tests on github are failing because it's testing with
8.x-1.xbranch for Replication module and this branch doesn't contain thereplication_settingsentity type from: https://github.com/relaxedws/drupal-replication/pull/12/files yet.@josephdpurcell you can modify the
drupal-8.1.x.make.ymlanddrupal-8.2.x.make.ymlfiles (in https://github.com/timmillwood/drupal-workspace/pull/7) to test with your branch (from Replication).@josephdpurcell Please commit changes from this patch to your branch on github: https://github.com/timmillwood/drupal-workspace/pull/7
Comment #28
phenaproximaNice work, @jeqq. This is already a lot cleaner and more reusable. I have two points, though:
There's nothing about this method that flat-out /requires/ the replication settings source to be a workspace, so let's change this to EntityInterface, simply as a risk-free, pre-emptive defense against bizarre edge cases).
Also, the parameter needs a description.
I'd rather we passed the full field name in here, rather than the 'push' or 'pull' prefix -- just in case the field has a completely different name. Again, that's an edge case, but if it's easy for us to nip those in the bud then let's do that.
Comment #29
josephdpurcell commentedThis patch uses #24 and addresses comments in #28.
@jeqq Thanks for the cleanup! And for finding the missing code on the replication module, I failed to create a ticket to address that.
I have opened #2781537: Add replication settings entity which is a dependency of this PR. For the time being I've modified the GitHub PR to use the branch for that ticket.
Comment #33
phenaproximaThis looks great! My only complaints are really just nit-scale.
Nit: For consistency, let's make this public static rather than static public :)
Should be \Drupal\Core\Entity\EntityInterface.
Needs description.
Needs @inheritdoc.
I think you can use $this->assertSession()->statusCodeEquals(200) here...
This isn't an assertion; are you sure you don't want to use one? I think there's got to be something in $this->assertSession() which would work...
Comment #34
josephdpurcell commentedComment #35
josephdpurcell commentedComment #39
damienmckenna@josephdpurcell: Please make sure to reroll the patch against the latest 8.x-1.x codebase, your patch doesn't apply.
Comment #40
josephdpurcell commentedReroll of #34 with updated 8.x-1.x branch.
Comment #41
phenaproximaAs far as I'm concerned, this is RTBC.
Comment #42
damienmckennaA minor change to use the correct replacement for assertResponse() (and instead of the assertEquals() calls that were being used).
Comment #46
damienmckennaThe test failures boil down to this one error:
Thoughts?
Comment #47
damienmckennaSo while comment #14 says "The tests are passing on GitHub: https://github.com/timmillwood/drupal-workspace/pull/7" we wouldn't want to commit a patch that would break every test run from then on.
Comment #48
damienmckennaMaybe the Replication module should be enabled as part of the tests?
Comment #49
damienmckennaComment #56
jeqq commented@DamienMcKenna This will fail on d.o because this functionality depend on other new functionality in Replication module (it's not yet commited). See #24. Now we are testing this on github: https://github.com/timmillwood/drupal-workspace/pull/7
Comment #57
damienmckenna@jeqq: Oh, grr :( Hopefully the d.o repo will be synchronized soon.
So, lets ignore the patches in #48.
Comment #58
josephdpurcell commentedThis patch fixes the error in the 8.2 tests seen https://github.com/timmillwood/drupal-workspace/pull/7
Comment #62
phenaproximaI have one defensive concern and one nitpick, and once these are addressed this is RTBC.
If $items is not valid, do we still want to return an empty ReplicationTask? It seems like we might want to fail with an exception here.
Nit: The description should come before @var and they should be separated by a blank line.
Comment #63
josephdpurcell commentedAfter some changes were made to #2781537: Add replication settings entity I believe this needs revisited. I will do so after final review on the #2781537: Add replication settings entity ticket is complete.
Comment #64
josephdpurcell commentedThanks for the great review--let's see if tests pass on github: https://travis-ci.org/timmillwood/drupal-workspace/builds/151668986
Comment #65
josephdpurcell commentedThere was one test fail: https://travis-ci.org/timmillwood/drupal-workspace/jobs/151809113. However, it is unclear why. I've noticed that test is flaky on my local and all the other tests pass: https://travis-ci.org/timmillwood/drupal-workspace/builds/151809111
As such, perhaps those tests could be re-run or the one test failure ignored?
Comment #66
jeqq commented@josephdpurcell the test is passing now.
Comment #67
josephdpurcell commentedGreat! Thanks for re-running it. I'll set this to needs review just so there's a record.
Comment #74
jeqq commentedI've tried to do manual testing. Push replication works fine but pull replication (update) fails with this error:
Comment #75
josephdpurcell commentedThe replicator manager service wasn't set. I also notice the wrong replication settings were populated. Both are fixed in this patch.
Comment #79
jeqq commentedI think replicator manager should be injected here, FormBase implements ContainerInjectionInterface.
Comment #80
josephdpurcell commentedI was following the pattern that existed. However, I agree--it should have dependencies injected.
I've refactored the form to have its dependencies injected.
Comment #81
phenaproximaThis is injected, and passed into the constructor, but $this->renderer is never actually set in __construct()...?
$form is not an object. :)
s/ajax/AJAX or Ajax
Comment #85
josephdpurcell commentedComment #89
phenaproximaThe patch looks great. I love it. Excellent work, @josephdpurcell!
The tests are only failing because this patch needs the HEAD of various other modules, but Drupal CI doesn't support that yet. As long as the tests pass on GitHub -- and they do -- we can march happily forward. It is my pleasure to mark this RTBC.
Comment #90
josephdpurcell commentedRemoves the changes to the travis makefiles (.travis/drupal-8.1.x.make.yml and .travis/drupal-8.2.x.make.yml).
Leaving this as RTBC, however important reminder that this will fail without #2781537: Add replication settings entity.
Comment #94
josephdpurcell commentedSetting back to RTBC per comments above.
Comment #95
jeqq commentedTests in Travis are also failing because of this problem (some of them don't return the correct status): https://travis-ci.org/timmillwood/drupal-workspace/builds/152436700.
A typo here.
I'll also do manual testing of the functionality.
Update:
After manual testing I've detected that replication doesn't work correctly when doing deploy (with Deploy module). The problem is in
ReplicatorManager::replicate(), before doing push replication (this line:$push_log = $this->doReplication($source, $target, $task);) we should define the task if it is null. Something like this:Comment #96
josephdpurcell commentedI suspect that the manual testing failed from the module not properly getting installed. The logic *should* properly handle the case where a $task does not exist. I tested it manually on my local and it seems to function.
Would you mind validating it works for you as well?
Comment #100
josephdpurcell commentedAdding additional missing use statements.
Comment #104
jeqq commented@josephdpurcell I've missed your last message from #96 yesterday. When I tested it, the push replication didn't work. For example when doing it like this (an example from Deploy module
ReplicationForm::save()):\Drupal::service('workspace.replicator_manager')->replicate($source, $target);That because the task is null in this case. It looks obvious to me because we should check for replication settings both on pull and push replication (we do both replication types in
ReplicatorManager::replicate(), but check for settings just on pull). If the task is null, inInternalReplicator::replicate()it defines a new task without replication setting.My solution from #95 fixes this. Does this make sense?
Comment #105
josephdpurcell commented@jeqq I've been in the weeds of this for a while, so thank you for giving this a thoughtful look, but also please have patience--it will be easy for me to miss the obvious (Linus' Law is a blessing and a curse!).
I do not see the issue, unfortunately. I will attempt to clarify my perspective with the hope you can identify the flaw.
General commentary
High level goal: this implementation should be backwards compatible with any other module, e.g. Deploy or Relaxed.
The primary way to achieve that was by making the added parameter optional like so:
So, the example from Deploy module, ReplicationForm::save(), should execute without alteration of behavior.
More specific commentary
In ReplicatorManager::replicate there is a "pull" replication as well as a "push" replication.
pull: The objective of the pull is to ensure there's no conflicts, hence these lines:
Assuming Deploy has a dependency on Workspace module, the above code should execute without alteration of Deploy's behavior. The getTask() call should return an instance of ReplicationTask without alteration (similar to what we see line 108 of InternalReplicator::replicate). The purpose of using an empty ReplicationTask object is to provide default values. There are other patterns for handling defaults, but I like the idea of using the default property values of a value object as the defaults.
push: The push replication step should also execute without alteration. Assuming NULL is passed in for the $task parameter, that should get passed on to the InternalReplicator (or other ReplicatorInterface) and the replicator should use default values.
Conclusion
I've tested this patch manually with Deploy, Workspace, Workbench Moderation, Replication, and Multiversion installed and Deploy appears to work correctly:
As I type this, however, I realize Workbench Moderation is not required--so I'll re-test this without that module.
It would be worthwhile to also validate that Relaxed works correctly with this patch. If I have time I will test with that.
Comment #106
josephdpurcell commentedI tested what I described in #105 without Workbench Moderation installed and the deployment succeeded.
@jeqq For next steps, I think the most expedient path would be to submit a patch with the changes you see required or make a comment on the lines of code that should change and I would be happy to make those changes--doing this would give concrete code changes we can discuss.
Comment #107
jeqq commented@josephdpurcell I've described all steps to reproduce the problem and attached the patch with the proposed solution.
Conclusion: When a workspace have Replication settings on deploy filter set, the push replication doesn’t work (we have the Live workspace in the previous example). For Stage workspace push replication works fine because it doesn’t have a Replication settings on deploy filter set.
Comment #111
josephdpurcell commentedAh! It's extremely obvious to me now what the problem is.
The ReplicatorManager::replicate assumes the $task that will be used will get passed to the method. However, Deploy does not do that. So, the question is, how should Workspace respond? @jeqq your suggestion is Workspace should derive the task for Deploy.
At least in my own mind, a Pandora's box has been opened. I have more questions now about how Workspace is designed and whether we've created two inconsistencies in the UI: one for how replication is triggered and one for how replication settings are defined/configured.
Deploy, Workspace, Workbench Moderation, Relaxed UX Conflict
Deploy:
Workspace (with Workbench Moderation):
Relaxed (with Workbench Moderation):
Relaxed (with Deploy):
Commentary:
I see two approaches: (1) allow each module to provide the way in which replication settings are derived for the replication, or (2) have the replication settings always derived from the Workspace. Right now it's hybrid: you can pass in a task or have it derived--I think it would be good to choose one approach or the other and refactor ReplicatorManager to comply with it: in the case of (1) refactor ReplicatorManager to know nothing about replication settings being on workspaces and force the push and pull replication settings be passed in, or (2) refactor ReplicatorManager to not allow passing in a replication task and just derive it at will.
I'm going to hold off on proceeding with this ticket until I've had a more in depth conversation on how this should work for the user.
Comment #112
JamesK commentedDeploy doesn't make sense without Workspace. IMO Deploy-triggered replications should use the Workspace replication settings.
Comment #113
josephdpurcell commentedAfter discussing this with @phenaproxima and @dixon_ we're going to take the pragmatic route of using a conditional as @jeqq suggested: this means that any module using Workspace should assume the replication settings come from the Workspace.
This patch uses #107 but also adds some comments and changes the Workspace that is used to derive the replication settings: they should always come from the Workspace being replicated to, i.e. the "target" Workspace.
For the longer term, the focus will be two things:
I don't have time to address these two points at present but will do so this week.
Comment #117
jeqq commented@josephdpurcell These changes look wrong to me:
In this case content will be replicated from
$targetworkspace to$sourceworkspace, so,$sourceis the target. Setting should come from$source.Logically, on push replication, settings should come from
$sourceworkspace, otherwise push replication settings doesn't make sense.Comment #118
josephdpurcell commented@jeqq The confusion is warranted, imo. I think the DX here can be improved to clarify what should happen.
I switched them back--you're absolutely right. The task should be derived on the workspace being acted on, most often this is the live workspace.
I also did a few code cleanups.
Comment #122
jeqq commentedCommited: http://cgit.drupalcode.org/workspace/commit/?id=35fdcf8
Thank you @josephdpurcell and @phenaproxima!