Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
With the merging of #2710947: Support replication filters there is now a ReplicationTask that can be used on ReplicatorInterface. This task class allows passing replication settings similar to the CouchDB spec: http://docs.couchdb.org/en/1.6.1/json-structure.html#replication-settings
This task if for utlizing the ReplicationTask on all ReplicatorInterfaces in Workspace.
Comment | File | Size | Author |
---|---|---|---|
#118 | interdiff_113-118.txt | 4.67 KB | josephdpurcell |
#118 | 2749167_118.patch | 29.78 KB | josephdpurcell |
#113 | interdiff_107-113.txt | 1.92 KB | josephdpurcell |
#113 | interdiff_100-113.txt | 1.83 KB | josephdpurcell |
#113 | 2749167_113.patch | 28.08 KB | josephdpurcell |
Comments
Comment #2
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedComment #3
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedComment #5
timmillwoodComment #7
timmillwoodMerged this, but still needs tests.
Comment #11
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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
BrowserTestBase
like 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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@josephdpurcell Tests are failing in Travis too: https://travis-ci.org/timmillwood/drupal-workspace/jobs/150725700
Comment #24
jeqq@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.x
branch for Replication module and this branch doesn't contain thereplication_settings
entity type from: https://github.com/relaxedws/drupal-replication/pull/12/files yet.@josephdpurcell you can modify the
drupal-8.1.x.make.yml
anddrupal-8.2.x.make.yml
files (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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedComment #35
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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@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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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@josephdpurcell the test is passing now.
Comment #67
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedGreat! Thanks for re-running it. I'll set this to needs review just so there's a record.
Comment #74
jeqqI've tried to do manual testing. Push replication works fine but pull replication (update) fails with this error:
Comment #75
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedThe replicator manager service wasn't set. I also notice the wrong replication settings were populated. Both are fixed in this patch.
Comment #79
jeqqI think replicator manager should be injected here, FormBase implements ContainerInjectionInterface.
Comment #80
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedSetting back to RTBC per comments above.
Comment #95
jeqqTests 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia commentedAdding additional missing use statements.
Comment #104
jeqq@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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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@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 CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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 CreditAttribution: JamesK at Advisor Websites commentedDeploy doesn't make sense without Workspace. IMO Deploy-triggered replications should use the Workspace replication settings.
Comment #113
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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@josephdpurcell These changes look wrong to me:
In this case content will be replicated from
$target
workspace to$source
workspace, so,$source
is the target. Setting should come from$source
.Logically, on push replication, settings should come from
$source
workspace, otherwise push replication settings doesn't make sense.Comment #118
josephdpurcell CreditAttribution: josephdpurcell at Digital Bridge Solutions for Acquia 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
jeqqCommited: http://cgit.drupalcode.org/workspace/commit/?id=35fdcf8
Thank you @josephdpurcell and @phenaproxima!