github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/db/globals.go (about) 1 package db 2 3 import ( 4 "gopkg.in/mgo.v2" 5 "gopkg.in/mgo.v2/bson" 6 ) 7 8 const ( 9 GlobalsCollection = "globals" 10 ) 11 12 // Global stores internal tracking information. 13 type Global struct { 14 BuildVariant string `bson:"_id"` 15 LastBuildNumber uint64 `bson:"last_build_number"` 16 LastTaskNumber uint64 `bson:"last_task_number"` 17 } 18 19 // GetNewBuildVariantTaskNumber atomically gets a new number for a task, 20 // given its variant name. 21 func GetNewBuildVariantTaskNumber(buildVariant string) (uint64, error) { 22 session, db, err := GetGlobalSessionFactory().GetSession() 23 if err != nil { 24 return 0, err 25 } 26 defer session.Close() 27 28 // get the record for this build variant 29 global := Global{} 30 err = db.C(GlobalsCollection).Find(bson.M{"_id": buildVariant}).One(&global) 31 32 // if this is the first task for 33 // this build variant, insert it 34 if err != nil && err == mgo.ErrNotFound { 35 change := mgo.Change{ 36 Update: bson.M{"$inc": bson.M{"last_task_number": 1}}, 37 Upsert: true, 38 ReturnNew: true, 39 } 40 41 _, err = db.C(GlobalsCollection).Find(bson.M{"_id": buildVariant}).Apply(change, &global) 42 if err != nil { 43 return 0, err 44 } 45 return global.LastTaskNumber, nil 46 } 47 48 // use the current build number the first time 49 // any client requests the build variant's task number 50 var newBuildVariantTaskNumber uint64 51 if global.LastTaskNumber == uint64(0) { 52 newBuildVariantTaskNumber = global.LastBuildNumber 53 } else { 54 newBuildVariantTaskNumber = global.LastTaskNumber + 1 55 } 56 change := mgo.Change{ 57 Update: bson.M{"$set": bson.M{ 58 "last_task_number": newBuildVariantTaskNumber, 59 }}, 60 ReturnNew: true, 61 } 62 63 _, err = db.C(GlobalsCollection).Find(bson.M{"_id": buildVariant}).Apply(change, &global) 64 65 if err != nil { 66 return 0, err 67 } 68 69 return global.LastTaskNumber, nil 70 } 71 72 // GetNewBuildVariantBuildNumber atomically gets a new number for a build, 73 // given its variant name. 74 func GetNewBuildVariantBuildNumber(buildVariant string) (uint64, error) { 75 session, db, err := GetGlobalSessionFactory().GetSession() 76 if err != nil { 77 return 0, err 78 } 79 defer session.Close() 80 81 // get the record for this build variant 82 global := Global{} 83 err = db.C(GlobalsCollection).Find(bson.M{"_id": buildVariant}).One(&global) 84 85 // if this is the first build for this 86 // this build variant, insert it 87 if err != nil && err == mgo.ErrNotFound { 88 change := mgo.Change{ 89 Update: bson.M{"$inc": bson.M{"last_build_number": 1}}, 90 Upsert: true, 91 ReturnNew: true, 92 } 93 94 _, err = db.C(GlobalsCollection).Find(bson.M{"_id": buildVariant}).Apply(change, &global) 95 if err != nil { 96 return 0, err 97 } 98 return global.LastBuildNumber, nil 99 } 100 101 // At this point, we know we've 102 // seen this build variant before 103 // find and modify last build variant number 104 change := mgo.Change{ 105 Update: bson.M{"$inc": bson.M{"last_build_number": 1}}, 106 ReturnNew: true, 107 } 108 109 _, err = db.C(GlobalsCollection).Find(bson.M{"_id": buildVariant}).Apply(change, &global) 110 111 if err != nil { 112 return 0, err 113 } 114 115 return global.LastBuildNumber, nil 116 }