github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/state/lease/doc.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 /* 5 6 The lease package exists to implement distributed lease management on top of 7 mgo/txn, and to expose assert operations that allow us to gate other mgo/txn 8 transactions on lease state. This necessity has affected the package; but, 9 apart from leaking assertion operations, it functions as a distributed lease- 10 management system with various useful properties. 11 12 These properties of course rest upon assumptions; ensuring the validity of the 13 following statements is the job of the client. 14 15 * The lease package has exclusive access to any collection it's configured 16 to use. (Please don't store anything else in there.) 17 18 * Given any (collection,namespace) pair, any client Id will be unique at any 19 given point in time. (Run no more than one per namespace per server, and 20 identify them according to where they're running). 21 22 * Global time (i.e. the time returned by the provided global clock) passes 23 no faster than wall-clock time. 24 25 So long as the above holds true, the following statements will too: 26 27 * A successful ClaimLease guarantees lease ownership until *at least* the 28 requested duration after the start of the call. (It does *not* guaranntee 29 any sort of timely expiry.) 30 31 * A successful ExtendLease makes the same guarantees. (In particular, note 32 that this cannot cause a lease to be shortened; but that success may 33 indicate ownership is guaranteed for longer than requested.) 34 35 * ExpireLease will only succeed when the global time is after the 36 (start+duration) written to the lease. 37 38 39 Schema design 40 ------------- 41 42 For each namespace, we store a single document per lease. The lease document 43 holds the name, holder, global start time, duration, and writer of the lease. 44 45 46 Client usage considerations 47 --------------------------- 48 49 * Client operates at a relatively low level of abstraction. Claiming a held 50 lease will fail, even on behalf of the holder; expiring an expired lease 51 will fail; but at least we can allow lease extensions to race benignly, 52 because they don't involve ownership change and thus can't break promises. 53 54 * ErrInvalid is normal and expected; you should never pass that on to your 55 own clients, because it indicates that you tried to manipulate the client 56 in an impossible way. You can and should inspect Leases() and figure out 57 what to do instead; that may well be "return an error", but please be sure 58 to return your own error, suitable for your own level of abstraction. 59 60 * You *probably* shouldn't ever need to actually call Refresh. It's perfectly 61 safe to let state drift arbitrarily far out of sync; when you try to run 62 operations, you will either succeed by luck despite your aged cache... or, 63 if you fail, you'll get ErrInvalid and a fresh cache to inspect to find out 64 recent state. 65 66 * The expiry time returned via lease.Info is relative to the local system 67 clock, not the global time. The expiry time should only be used for 68 comparison with other local system clock times, and only with Go 1.9+ 69 (i.e. because Go 1.9 introduced monotonic time components.) 70 71 */ 72 package lease