state: Add support for sequences with a minimum #6839

Merged
merged 1 commit into from Jan 24, 2017

Conversation

Projects
None yet
4 participants
Contributor

mjs commented Jan 19, 2017

Added State.sequenceWithMin() and the infrastructure to support it. This
is like State.sequence() but allows a minimum value for a sequence to be
specified. This is surprisingly complicated to implement due to there
being no atomic way to provide initial values for an upserted counter in
MongoDB.

This is preparation for supporting tracking of which local charm URLs
have been used without having to keep dead charm documents.
See https://bugs.launchpad.net/juju/+bug/1657614

QA

This functionality isn't wired up yet but the unit tests, which include a live contention test, have been run under the stress tested on 2 machines for over an hour.

+ }
+ if curVal == 0 {
+ // No sequence document exists, create one.
+ ok, err := sequence.create(minVal + 1)
@howbazaar

howbazaar Jan 19, 2017

Owner

Am I right in remembering that the sequence values stores the next value of the sequence?

@mjs

mjs Jan 24, 2017

Contributor

Yes. I've added a comment to clarify this.

+ // No sequence document exists, create one.
+ ok, err := sequence.create(minVal + 1)
+ if err != nil {
+ return -1, errors.Annotate(err, "could not create sequence")
@howbazaar

howbazaar Jan 19, 2017

Owner

Is this really an error? Why not a retry?

Perhaps recording the semantics of the create method in the interface.

@mjs

mjs Jan 24, 2017

Contributor

I've documented the interface. This should make things clearer.

+ bson.M{"$set": bson.M{"counter": next}},
+ )
+ if errors.Cause(err) == mgo.ErrNotFound {
+ return false, nil
@howbazaar

howbazaar Jan 19, 2017

Owner

This seems weird to me. Why do we need this case?

@mjs

mjs Jan 24, 2017

Contributor

The update query includes the expected current value of the sequence. The update will fail if ErrNotFound if someone update the sequence, allowing detection of concurrent updates.

state/sequence_test.go
+ for i := 0; i < iterations; i++ {
+ v, err := nextSeq()
+ if err != nil {
+ fmt.Println(err)
@howbazaar

howbazaar Jan 19, 2017

Owner

Would be better to use c.Logf or a logger.

@mjs

mjs Jan 24, 2017

Contributor

Fixed.

state: Add support for sequences with a minimum
Added State.sequenceWithMin() and the infrastructure to support it. This
is like State.sequence() but allows a minimum value for a sequence to be
specified. This is surprisingly complicated to implement due to there
being no atomic way to provide initial values for an upserted counter in
MongoDB.

This is preparation for supporting tracking of which local charm URLs
have been used without having to keep dead charm documents.
See https://bugs.launchpad.net/juju/+bug/1657614

This looks good to me. I was a bit confused about returning -1 rather than 0 on errors, but I guess that's just being extra careful that the caller won't think this is a valid value.

Contributor

mjs commented Jan 24, 2017

$$merge$$

Contributor

jujubot commented Jan 24, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

@jujubot jujubot merged commit 518cb0c into juju:2.1 Jan 24, 2017

1 check passed

github-check-merge-juju Built PR, ran unit tests, and tested LXD deploy. Use !!.*!! to request another build. IE, !!build!!, !!retry!!
Details

@mjs mjs deleted the mjs:sequence-with-min branch Jan 24, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment