Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
If a change is no-op, then don't create a transaction. #7180
Conversation
jameinel
added some commits
Mar 30, 2017
jameinel
changed the title from
WIP: If a change is no-op, then don't create a transaction.
to
If a change is no-op, then don't create a transaction.
Mar 30, 2017
|
This currently does create no-op transactions that look like:
would it be better to raise an exception that there is nothing to do so that these don't get created? |
|
This has been fixed in the last version. |
jameinel
added some commits
Mar 30, 2017
axw
reviewed
Mar 31, 2017
Looks fine, but I have some concern about dropping the model life assertion. I don't think it needs to be there in the first place, in which case we should remove both parts. But if we do care and must check in memory, we should be mirroring that in an assert.
| + if err := checkModelActive(m.st); err != nil { | ||
| + return nil, errors.Trace(err) | ||
| + } | ||
| + if err := m.isStillAlive(); err != nil { |
axw
Mar 31, 2017
Member
it would be a little more efficient to use the m.doc.Life value here, and only reload the machine doc on attempt>0. I suspect that's what was intended originally, except the initial check was left out
| @@ -206,18 +206,27 @@ func (m *Machine) SetLinkLayerDevices(devicesArgs ...LinkLayerDeviceArgs) (err e | ||
| } | ||
| } | ||
| + // We've checked the model is alive directly, and we assert the machine is alive, we don't need to also | ||
| + // assert the model is alive, because then the machine would be dying as well. |
axw
Mar 31, 2017
Member
This statement is not true. A model can be dying, but still have alive machines. They will eventually be destroyed on account of cleanups.
If we don't really care about the model life here, should we remove the one above too? The doc comment for the method does not explain why we check the model life. Do you know?
jameinel
Apr 3, 2017
Owner
I think it was back in the "I'm updating something, make sure my model is alive". These aren't actually creating new resources, so I don't think it is critical.
I'm personally ok with a "don't start work that is about to be dropped" check of model, but certainly I don't believe we need the TXN assert.
axw
Apr 3, 2017
Member
I think you're right, and we should only care about checking model life when creating new resources.
IMO, the in-memory life check should be dropped too. It's of dubious value when there's no accompanying txn op, since it's no longer ensuring integrity - so it's really just an optimisation. This makes things more difficult to understand, because it's not clear why we would do it in only memory from the context (hence this question).
FWIW, I've taken to the pattern of:
// checkSomething checks something in memory, and then return txn.Ops that assert the same
func checkSomething() ([]txn.Op, error)That way it's clear that the ops will be ignored or not, more likely with comments to justify.
| + if len(setDevicesOps) == 0 { | ||
| + // No need to assert only that the machine is alive | ||
| + logger.Debugf("no changes to LinkLayerDevices for machine %q", m.Id()) | ||
| + return nil, errNoChanges |
jameinel
Apr 3, 2017
Owner
thanks, I expected something like that, but there wasn't anything like that around this code.
| @@ -206,18 +206,27 @@ func (m *Machine) SetLinkLayerDevices(devicesArgs ...LinkLayerDeviceArgs) (err e | ||
| } | ||
| } | ||
| + // We've checked the model is alive directly, and we assert the machine is alive, we don't need to also | ||
| + // assert the model is alive, because then the machine would be dying as well. |
axw
Mar 31, 2017
Member
This statement is not true. A model can be dying, but still have alive machines. They will eventually be destroyed on account of cleanups.
If we don't really care about the model life here, should we remove the one above too? The doc comment for the method does not explain why we check the model life. Do you know?
jameinel
Apr 3, 2017
Owner
I think it was back in the "I'm updating something, make sure my model is alive". These aren't actually creating new resources, so I don't think it is critical.
I'm personally ok with a "don't start work that is about to be dropped" check of model, but certainly I don't believe we need the TXN assert.
axw
Apr 3, 2017
Member
I think you're right, and we should only care about checking model life when creating new resources.
IMO, the in-memory life check should be dropped too. It's of dubious value when there's no accompanying txn op, since it's no longer ensuring integrity - so it's really just an optimisation. This makes things more difficult to understand, because it's not clear why we would do it in only memory from the context (hence this question).
FWIW, I've taken to the pattern of:
// checkSomething checks something in memory, and then return txn.Ops that assert the same
func checkSomething() ([]txn.Op, error)That way it's clear that the ops will be ignored or not, more likely with comments to justify.
| @@ -600,13 +615,13 @@ func (m *Machine) SetDevicesAddresses(devicesAddresses ...LinkLayerDeviceAddress | ||
| return nil, errors.Trace(err) | ||
| } | ||
| + if err := checkModelActive(m.st); err != nil { |
|
$$merge$$ |
|
Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju |
|
Build failed: Generating tarball failed |
|
$$merge$$ |
|
Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju |
jameinel commentedMar 30, 2017
•
Edited 1 time
-
jameinel
Mar 30, 2017
Description of change
Change SetLinkLayerDevices and SetDevicesAddresses so that both of them check if there are actually any changes to be done, and only if we'll actually change something do we create a transaction.
QA steps
monitor the transaction log, it should not be filling up with transactions that are ultimately just asserting that a bunch of devices still exist. The debug-log should also include lines like:
should return no documents. Before the last commit we were creating transactions that affected no collections, which was a bit silly.
Documentation changes
None.
Bug reference
lp:1677619
lp:1676427